PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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/hash.h"
16 #include "catalog/pg_type.h"
17 #include "common/ip.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"
23 
24 
26 static bool addressOK(unsigned char *a, int bits, int family);
27 static inet *internal_inetpl(inet *ip, int64 addend);
28 
29 
30 /*
31  * Common INET/CIDR input routine
32  */
33 static inet *
34 network_in(char *src, bool is_cidr)
35 {
36  int bits;
37  inet *dst;
38 
39  dst = (inet *) palloc0(sizeof(inet));
40 
41  /*
42  * First, check to see if this is an IPv6 or IPv4 address. IPv6 addresses
43  * will have a : somewhere in them (several, in fact) so if there is one
44  * present, assume it's V6, otherwise assume it's V4.
45  */
46 
47  if (strchr(src, ':') != NULL)
49  else
50  ip_family(dst) = PGSQL_AF_INET;
51 
52  bits = inet_net_pton(ip_family(dst), src, ip_addr(dst),
53  is_cidr ? ip_addrsize(dst) : -1);
54  if ((bits < 0) || (bits > ip_maxbits(dst)))
55  ereport(ERROR,
56  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
57  /* translator: first %s is inet or cidr */
58  errmsg("invalid input syntax for type %s: \"%s\"",
59  is_cidr ? "cidr" : "inet", src)));
60 
61  /*
62  * Error check: CIDR values must not have any bits set beyond the masklen.
63  */
64  if (is_cidr)
65  {
66  if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
67  ereport(ERROR,
68  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
69  errmsg("invalid cidr value: \"%s\"", src),
70  errdetail("Value has bits set to right of mask.")));
71  }
72 
73  ip_bits(dst) = bits;
74  SET_INET_VARSIZE(dst);
75 
76  return dst;
77 }
78 
79 Datum
81 {
82  char *src = PG_GETARG_CSTRING(0);
83 
84  PG_RETURN_INET_P(network_in(src, false));
85 }
86 
87 Datum
89 {
90  char *src = PG_GETARG_CSTRING(0);
91 
92  PG_RETURN_INET_P(network_in(src, true));
93 }
94 
95 
96 /*
97  * Common INET/CIDR output routine
98  */
99 static char *
100 network_out(inet *src, bool is_cidr)
101 {
102  char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
103  char *dst;
104  int len;
105 
106  dst = inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
107  tmp, sizeof(tmp));
108  if (dst == NULL)
109  ereport(ERROR,
110  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
111  errmsg("could not format inet value: %m")));
112 
113  /* For CIDR, add /n if not present */
114  if (is_cidr && strchr(tmp, '/') == NULL)
115  {
116  len = strlen(tmp);
117  snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
118  }
119 
120  return pstrdup(tmp);
121 }
122 
123 Datum
125 {
126  inet *src = PG_GETARG_INET_PP(0);
127 
128  PG_RETURN_CSTRING(network_out(src, false));
129 }
130 
131 Datum
133 {
134  inet *src = PG_GETARG_INET_PP(0);
135 
136  PG_RETURN_CSTRING(network_out(src, true));
137 }
138 
139 
140 /*
141  * network_recv - converts external binary format to inet
142  *
143  * The external representation is (one byte apiece for)
144  * family, bits, is_cidr, address length, address in network byte order.
145  *
146  * Presence of is_cidr is largely for historical reasons, though it might
147  * allow some code-sharing on the client side. We send it correctly on
148  * output, but ignore the value on input.
149  */
150 static inet *
152 {
153  inet *addr;
154  char *addrptr;
155  int bits;
156  int nb,
157  i;
158 
159  /* make sure any unused bits in a CIDR value are zeroed */
160  addr = (inet *) palloc0(sizeof(inet));
161 
162  ip_family(addr) = pq_getmsgbyte(buf);
163  if (ip_family(addr) != PGSQL_AF_INET &&
164  ip_family(addr) != PGSQL_AF_INET6)
165  ereport(ERROR,
166  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
167  /* translator: %s is inet or cidr */
168  errmsg("invalid address family in external \"%s\" value",
169  is_cidr ? "cidr" : "inet")));
170  bits = pq_getmsgbyte(buf);
171  if (bits < 0 || bits > ip_maxbits(addr))
172  ereport(ERROR,
173  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
174  /* translator: %s is inet or cidr */
175  errmsg("invalid bits in external \"%s\" value",
176  is_cidr ? "cidr" : "inet")));
177  ip_bits(addr) = bits;
178  i = pq_getmsgbyte(buf); /* ignore is_cidr */
179  nb = pq_getmsgbyte(buf);
180  if (nb != ip_addrsize(addr))
181  ereport(ERROR,
182  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
183  /* translator: %s is inet or cidr */
184  errmsg("invalid length in external \"%s\" value",
185  is_cidr ? "cidr" : "inet")));
186 
187  addrptr = (char *) ip_addr(addr);
188  for (i = 0; i < nb; i++)
189  addrptr[i] = pq_getmsgbyte(buf);
190 
191  /*
192  * Error check: CIDR values must not have any bits set beyond the masklen.
193  */
194  if (is_cidr)
195  {
196  if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
197  ereport(ERROR,
198  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
199  errmsg("invalid external \"cidr\" value"),
200  errdetail("Value has bits set to right of mask.")));
201  }
202 
203  SET_INET_VARSIZE(addr);
204 
205  return addr;
206 }
207 
208 Datum
210 {
212 
213  PG_RETURN_INET_P(network_recv(buf, false));
214 }
215 
216 Datum
218 {
220 
221  PG_RETURN_INET_P(network_recv(buf, true));
222 }
223 
224 
225 /*
226  * network_send - converts inet to binary format
227  */
228 static bytea *
229 network_send(inet *addr, bool is_cidr)
230 {
232  char *addrptr;
233  int nb,
234  i;
235 
236  pq_begintypsend(&buf);
237  pq_sendbyte(&buf, ip_family(addr));
238  pq_sendbyte(&buf, ip_bits(addr));
239  pq_sendbyte(&buf, is_cidr);
240  nb = ip_addrsize(addr);
241  if (nb < 0)
242  nb = 0;
243  pq_sendbyte(&buf, nb);
244  addrptr = (char *) ip_addr(addr);
245  for (i = 0; i < nb; i++)
246  pq_sendbyte(&buf, addrptr[i]);
247  return pq_endtypsend(&buf);
248 }
249 
250 Datum
252 {
253  inet *addr = PG_GETARG_INET_PP(0);
254 
255  PG_RETURN_BYTEA_P(network_send(addr, false));
256 }
257 
258 Datum
260 {
261  inet *addr = PG_GETARG_INET_PP(0);
262 
263  PG_RETURN_BYTEA_P(network_send(addr, true));
264 }
265 
266 
267 Datum
269 {
270  inet *src = PG_GETARG_INET_PP(0);
271  int bits;
272 
273  bits = ip_bits(src);
274 
275  /* safety check */
276  if ((bits < 0) || (bits > ip_maxbits(src)))
277  elog(ERROR, "invalid inet bit length: %d", bits);
278 
280 }
281 
282 Datum
284 {
285  inet *src = PG_GETARG_INET_PP(0);
286  int bits = PG_GETARG_INT32(1);
287  inet *dst;
288 
289  if (bits == -1)
290  bits = ip_maxbits(src);
291 
292  if ((bits < 0) || (bits > ip_maxbits(src)))
293  ereport(ERROR,
294  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
295  errmsg("invalid mask length: %d", bits)));
296 
297  /* clone the original data */
298  dst = (inet *) palloc(VARSIZE_ANY(src));
299  memcpy(dst, src, VARSIZE_ANY(src));
300 
301  ip_bits(dst) = bits;
302 
303  PG_RETURN_INET_P(dst);
304 }
305 
306 Datum
308 {
309  inet *src = PG_GETARG_INET_PP(0);
310  int bits = PG_GETARG_INT32(1);
311 
312  if (bits == -1)
313  bits = ip_maxbits(src);
314 
315  if ((bits < 0) || (bits > ip_maxbits(src)))
316  ereport(ERROR,
317  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
318  errmsg("invalid mask length: %d", bits)));
319 
321 }
322 
323 /*
324  * Copy src and set mask length to 'bits' (which must be valid for the family)
325  */
326 inet *
327 cidr_set_masklen_internal(const inet *src, int bits)
328 {
329  inet *dst = (inet *) palloc0(sizeof(inet));
330 
331  ip_family(dst) = ip_family(src);
332  ip_bits(dst) = bits;
333 
334  if (bits > 0)
335  {
336  Assert(bits <= ip_maxbits(dst));
337 
338  /* Clone appropriate bytes of the address, leaving the rest 0 */
339  memcpy(ip_addr(dst), ip_addr(src), (bits + 7) / 8);
340 
341  /* Clear any unwanted bits in the last partial byte */
342  if (bits % 8)
343  ip_addr(dst)[bits / 8] &= ~(0xFF >> (bits % 8));
344  }
345 
346  /* Set varlena header correctly */
347  SET_INET_VARSIZE(dst);
348 
349  return dst;
350 }
351 
352 /*
353  * Basic comparison function for sorting and inet/cidr comparisons.
354  *
355  * Comparison is first on the common bits of the network part, then on
356  * the length of the network part, and then on the whole unmasked address.
357  * The effect is that the network part is the major sort key, and for
358  * equal network parts we sort on the host part. Note this is only sane
359  * for CIDR if address bits to the right of the mask are guaranteed zero;
360  * otherwise logically-equal CIDRs might compare different.
361  */
362 
363 static int32
365 {
366  if (ip_family(a1) == ip_family(a2))
367  {
368  int order;
369 
370  order = bitncmp(ip_addr(a1), ip_addr(a2),
371  Min(ip_bits(a1), ip_bits(a2)));
372  if (order != 0)
373  return order;
374  order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
375  if (order != 0)
376  return order;
377  return bitncmp(ip_addr(a1), ip_addr(a2), ip_maxbits(a1));
378  }
379 
380  return ip_family(a1) - ip_family(a2);
381 }
382 
383 Datum
385 {
386  inet *a1 = PG_GETARG_INET_PP(0);
387  inet *a2 = PG_GETARG_INET_PP(1);
388 
390 }
391 
392 /*
393  * Boolean ordering tests.
394  */
395 Datum
397 {
398  inet *a1 = PG_GETARG_INET_PP(0);
399  inet *a2 = PG_GETARG_INET_PP(1);
400 
402 }
403 
404 Datum
406 {
407  inet *a1 = PG_GETARG_INET_PP(0);
408  inet *a2 = PG_GETARG_INET_PP(1);
409 
410  PG_RETURN_BOOL(network_cmp_internal(a1, a2) <= 0);
411 }
412 
413 Datum
415 {
416  inet *a1 = PG_GETARG_INET_PP(0);
417  inet *a2 = PG_GETARG_INET_PP(1);
418 
419  PG_RETURN_BOOL(network_cmp_internal(a1, a2) == 0);
420 }
421 
422 Datum
424 {
425  inet *a1 = PG_GETARG_INET_PP(0);
426  inet *a2 = PG_GETARG_INET_PP(1);
427 
428  PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0);
429 }
430 
431 Datum
433 {
434  inet *a1 = PG_GETARG_INET_PP(0);
435  inet *a2 = PG_GETARG_INET_PP(1);
436 
438 }
439 
440 Datum
442 {
443  inet *a1 = PG_GETARG_INET_PP(0);
444  inet *a2 = PG_GETARG_INET_PP(1);
445 
446  PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
447 }
448 
449 /*
450  * MIN/MAX support functions.
451  */
452 Datum
454 {
455  inet *a1 = PG_GETARG_INET_PP(0);
456  inet *a2 = PG_GETARG_INET_PP(1);
457 
458  if (network_cmp_internal(a1, a2) < 0)
459  PG_RETURN_INET_P(a1);
460  else
461  PG_RETURN_INET_P(a2);
462 }
463 
464 Datum
466 {
467  inet *a1 = PG_GETARG_INET_PP(0);
468  inet *a2 = PG_GETARG_INET_PP(1);
469 
470  if (network_cmp_internal(a1, a2) > 0)
471  PG_RETURN_INET_P(a1);
472  else
473  PG_RETURN_INET_P(a2);
474 }
475 
476 /*
477  * Support function for hash indexes on inet/cidr.
478  */
479 Datum
481 {
482  inet *addr = PG_GETARG_INET_PP(0);
483  int addrsize = ip_addrsize(addr);
484 
485  /* XXX this assumes there are no pad bytes in the data structure */
486  return hash_any((unsigned char *) VARDATA_ANY(addr), addrsize + 2);
487 }
488 
489 /*
490  * Boolean network-inclusion tests.
491  */
492 Datum
494 {
495  inet *a1 = PG_GETARG_INET_PP(0);
496  inet *a2 = PG_GETARG_INET_PP(1);
497 
498  if (ip_family(a1) == ip_family(a2))
499  {
500  PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2) &&
501  bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
502  }
503 
504  PG_RETURN_BOOL(false);
505 }
506 
507 Datum
509 {
510  inet *a1 = PG_GETARG_INET_PP(0);
511  inet *a2 = PG_GETARG_INET_PP(1);
512 
513  if (ip_family(a1) == ip_family(a2))
514  {
515  PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2) &&
516  bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
517  }
518 
519  PG_RETURN_BOOL(false);
520 }
521 
522 Datum
524 {
525  inet *a1 = PG_GETARG_INET_PP(0);
526  inet *a2 = PG_GETARG_INET_PP(1);
527 
528  if (ip_family(a1) == ip_family(a2))
529  {
530  PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2) &&
531  bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
532  }
533 
534  PG_RETURN_BOOL(false);
535 }
536 
537 Datum
539 {
540  inet *a1 = PG_GETARG_INET_PP(0);
541  inet *a2 = PG_GETARG_INET_PP(1);
542 
543  if (ip_family(a1) == ip_family(a2))
544  {
545  PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2) &&
546  bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
547  }
548 
549  PG_RETURN_BOOL(false);
550 }
551 
552 Datum
554 {
555  inet *a1 = PG_GETARG_INET_PP(0);
556  inet *a2 = PG_GETARG_INET_PP(1);
557 
558  if (ip_family(a1) == ip_family(a2))
559  {
561  Min(ip_bits(a1), ip_bits(a2))) == 0);
562  }
563 
564  PG_RETURN_BOOL(false);
565 }
566 
567 /*
568  * Extract data from a network datatype.
569  */
570 Datum
572 {
573  inet *ip = PG_GETARG_INET_PP(0);
574  char *ptr;
575  char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
576 
577  /* force display of max bits, regardless of masklen... */
578  if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
579  tmp, sizeof(tmp)) == NULL)
580  ereport(ERROR,
581  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
582  errmsg("could not format inet value: %m")));
583 
584  /* Suppress /n if present (shouldn't happen now) */
585  if ((ptr = strchr(tmp, '/')) != NULL)
586  *ptr = '\0';
587 
589 }
590 
591 /*
592  * network_show implements the inet and cidr casts to text. This is not
593  * quite the same behavior as network_out, hence we can't drop it in favor
594  * of CoerceViaIO.
595  */
596 Datum
598 {
599  inet *ip = PG_GETARG_INET_PP(0);
600  int len;
601  char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
602 
603  if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
604  tmp, sizeof(tmp)) == NULL)
605  ereport(ERROR,
606  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
607  errmsg("could not format inet value: %m")));
608 
609  /* Add /n if not present (which it won't be) */
610  if (strchr(tmp, '/') == NULL)
611  {
612  len = strlen(tmp);
613  snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
614  }
615 
617 }
618 
619 Datum
621 {
622  inet *ip = PG_GETARG_INET_PP(0);
623  char *dst;
624  char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
625 
626  dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
627  ip_bits(ip), tmp, sizeof(tmp));
628 
629  if (dst == NULL)
630  ereport(ERROR,
631  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
632  errmsg("could not format inet value: %m")));
633 
635 }
636 
637 Datum
639 {
640  inet *ip = PG_GETARG_INET_PP(0);
641  char *dst;
642  char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
643 
644  dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
645  ip_bits(ip), tmp, sizeof(tmp));
646 
647  if (dst == NULL)
648  ereport(ERROR,
649  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
650  errmsg("could not format cidr value: %m")));
651 
653 }
654 
655 Datum
657 {
658  inet *ip = PG_GETARG_INET_PP(0);
659 
661 }
662 
663 Datum
665 {
666  inet *ip = PG_GETARG_INET_PP(0);
667 
668  switch (ip_family(ip))
669  {
670  case PGSQL_AF_INET:
671  PG_RETURN_INT32(4);
672  break;
673  case PGSQL_AF_INET6:
674  PG_RETURN_INT32(6);
675  break;
676  default:
677  PG_RETURN_INT32(0);
678  break;
679  }
680 }
681 
682 Datum
684 {
685  inet *ip = PG_GETARG_INET_PP(0);
686  inet *dst;
687  int byte;
688  int bits;
689  int maxbytes;
690  unsigned char mask;
691  unsigned char *a,
692  *b;
693 
694  /* make sure any unused bits are zeroed */
695  dst = (inet *) palloc0(sizeof(inet));
696 
697  maxbytes = ip_addrsize(ip);
698  bits = ip_bits(ip);
699  a = ip_addr(ip);
700  b = ip_addr(dst);
701 
702  for (byte = 0; byte < maxbytes; byte++)
703  {
704  if (bits >= 8)
705  {
706  mask = 0x00;
707  bits -= 8;
708  }
709  else if (bits == 0)
710  mask = 0xff;
711  else
712  {
713  mask = 0xff >> bits;
714  bits = 0;
715  }
716 
717  b[byte] = a[byte] | mask;
718  }
719 
720  ip_family(dst) = ip_family(ip);
721  ip_bits(dst) = ip_bits(ip);
722  SET_INET_VARSIZE(dst);
723 
724  PG_RETURN_INET_P(dst);
725 }
726 
727 Datum
729 {
730  inet *ip = PG_GETARG_INET_PP(0);
731  inet *dst;
732  int byte;
733  int bits;
734  unsigned char mask;
735  unsigned char *a,
736  *b;
737 
738  /* make sure any unused bits are zeroed */
739  dst = (inet *) palloc0(sizeof(inet));
740 
741  bits = ip_bits(ip);
742  a = ip_addr(ip);
743  b = ip_addr(dst);
744 
745  byte = 0;
746 
747  while (bits)
748  {
749  if (bits >= 8)
750  {
751  mask = 0xff;
752  bits -= 8;
753  }
754  else
755  {
756  mask = 0xff << (8 - bits);
757  bits = 0;
758  }
759 
760  b[byte] = a[byte] & mask;
761  byte++;
762  }
763 
764  ip_family(dst) = ip_family(ip);
765  ip_bits(dst) = ip_bits(ip);
766  SET_INET_VARSIZE(dst);
767 
768  PG_RETURN_INET_P(dst);
769 }
770 
771 Datum
773 {
774  inet *ip = PG_GETARG_INET_PP(0);
775  inet *dst;
776  int byte;
777  int bits;
778  unsigned char mask;
779  unsigned char *b;
780 
781  /* make sure any unused bits are zeroed */
782  dst = (inet *) palloc0(sizeof(inet));
783 
784  bits = ip_bits(ip);
785  b = ip_addr(dst);
786 
787  byte = 0;
788 
789  while (bits)
790  {
791  if (bits >= 8)
792  {
793  mask = 0xff;
794  bits -= 8;
795  }
796  else
797  {
798  mask = 0xff << (8 - bits);
799  bits = 0;
800  }
801 
802  b[byte] = mask;
803  byte++;
804  }
805 
806  ip_family(dst) = ip_family(ip);
807  ip_bits(dst) = ip_maxbits(ip);
808  SET_INET_VARSIZE(dst);
809 
810  PG_RETURN_INET_P(dst);
811 }
812 
813 Datum
815 {
816  inet *ip = PG_GETARG_INET_PP(0);
817  inet *dst;
818  int byte;
819  int bits;
820  int maxbytes;
821  unsigned char mask;
822  unsigned char *b;
823 
824  /* make sure any unused bits are zeroed */
825  dst = (inet *) palloc0(sizeof(inet));
826 
827  maxbytes = ip_addrsize(ip);
828  bits = ip_maxbits(ip) - ip_bits(ip);
829  b = ip_addr(dst);
830 
831  byte = maxbytes - 1;
832 
833  while (bits)
834  {
835  if (bits >= 8)
836  {
837  mask = 0xff;
838  bits -= 8;
839  }
840  else
841  {
842  mask = 0xff >> (8 - bits);
843  bits = 0;
844  }
845 
846  b[byte] = mask;
847  byte--;
848  }
849 
850  ip_family(dst) = ip_family(ip);
851  ip_bits(dst) = ip_maxbits(ip);
852  SET_INET_VARSIZE(dst);
853 
854  PG_RETURN_INET_P(dst);
855 }
856 
857 /*
858  * Returns true if the addresses are from the same family, or false. Used to
859  * check that we can create a network which contains both of the networks.
860  */
861 Datum
863 {
864  inet *a1 = PG_GETARG_INET_PP(0);
865  inet *a2 = PG_GETARG_INET_PP(1);
866 
867  PG_RETURN_BOOL(ip_family(a1) == ip_family(a2));
868 }
869 
870 /*
871  * Returns the smallest CIDR which contains both of the inputs.
872  */
873 Datum
875 {
876  inet *a1 = PG_GETARG_INET_PP(0),
877  *a2 = PG_GETARG_INET_PP(1);
878  int commonbits;
879 
880  if (ip_family(a1) != ip_family(a2))
881  ereport(ERROR,
882  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
883  errmsg("cannot merge addresses from different families")));
884 
885  commonbits = bitncommon(ip_addr(a1), ip_addr(a2),
886  Min(ip_bits(a1), ip_bits(a2)));
887 
889 }
890 
891 /*
892  * Convert a value of a network datatype to an approximate scalar value.
893  * This is used for estimating selectivities of inequality operators
894  * involving network types.
895  */
896 double
898 {
899  switch (typid)
900  {
901  case INETOID:
902  case CIDROID:
903  {
904  inet *ip = DatumGetInetPP(value);
905  int len;
906  double res;
907  int i;
908 
909  /*
910  * Note that we don't use the full address for IPv6.
911  */
912  if (ip_family(ip) == PGSQL_AF_INET)
913  len = 4;
914  else
915  len = 5;
916 
917  res = ip_family(ip);
918  for (i = 0; i < len; i++)
919  {
920  res *= 256;
921  res += ip_addr(ip)[i];
922  }
923  return res;
924 
925  break;
926  }
927  case MACADDROID:
928  {
929  macaddr *mac = DatumGetMacaddrP(value);
930  double res;
931 
932  res = (mac->a << 16) | (mac->b << 8) | (mac->c);
933  res *= 256 * 256 * 256;
934  res += (mac->d << 16) | (mac->e << 8) | (mac->f);
935  return res;
936  }
937  case MACADDR8OID:
938  {
939  macaddr8 *mac = DatumGetMacaddr8P(value);
940  double res;
941 
942  res = (mac->a << 24) | (mac->b << 16) | (mac->c << 8) | (mac->d);
943  res *= ((double) 256) * 256 * 256 * 256;
944  res += (mac->e << 24) | (mac->f << 16) | (mac->g << 8) | (mac->h);
945  return res;
946  }
947  }
948 
949  /*
950  * Can't get here unless someone tries to use scalarltsel/scalargtsel on
951  * an operator with one network and one non-network operand.
952  */
953  elog(ERROR, "unsupported type: %u", typid);
954  return 0;
955 }
956 
957 /*
958  * int
959  * bitncmp(l, r, n)
960  * compare bit masks l and r, for n bits.
961  * return:
962  * <0, >0, or 0 in the libc tradition.
963  * note:
964  * network byte order assumed. this means 192.5.5.240/28 has
965  * 0x11110000 in its fourth octet.
966  * author:
967  * Paul Vixie (ISC), June 1996
968  */
969 int
970 bitncmp(const unsigned char *l, const unsigned char *r, int n)
971 {
972  unsigned int lb,
973  rb;
974  int x,
975  b;
976 
977  b = n / 8;
978  x = memcmp(l, r, b);
979  if (x || (n % 8) == 0)
980  return x;
981 
982  lb = l[b];
983  rb = r[b];
984  for (b = n % 8; b > 0; b--)
985  {
986  if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
987  {
988  if (IS_HIGHBIT_SET(lb))
989  return 1;
990  return -1;
991  }
992  lb <<= 1;
993  rb <<= 1;
994  }
995  return 0;
996 }
997 
998 /*
999  * bitncommon: compare bit masks l and r, for up to n bits.
1000  *
1001  * Returns the number of leading bits that match (0 to n).
1002  */
1003 int
1004 bitncommon(const unsigned char *l, const unsigned char *r, int n)
1005 {
1006  int byte,
1007  nbits;
1008 
1009  /* number of bits to examine in last byte */
1010  nbits = n % 8;
1011 
1012  /* check whole bytes */
1013  for (byte = 0; byte < n / 8; byte++)
1014  {
1015  if (l[byte] != r[byte])
1016  {
1017  /* at least one bit in the last byte is not common */
1018  nbits = 7;
1019  break;
1020  }
1021  }
1022 
1023  /* check bits in last partial byte */
1024  if (nbits != 0)
1025  {
1026  /* calculate diff of first non-matching bytes */
1027  unsigned int diff = l[byte] ^ r[byte];
1028 
1029  /* compare the bits from the most to the least */
1030  while ((diff >> (8 - nbits)) != 0)
1031  nbits--;
1032  }
1033 
1034  return (8 * byte) + nbits;
1035 }
1036 
1037 
1038 /*
1039  * Verify a CIDR address is OK (doesn't have bits set past the masklen)
1040  */
1041 static bool
1042 addressOK(unsigned char *a, int bits, int family)
1043 {
1044  int byte;
1045  int nbits;
1046  int maxbits;
1047  int maxbytes;
1048  unsigned char mask;
1049 
1050  if (family == PGSQL_AF_INET)
1051  {
1052  maxbits = 32;
1053  maxbytes = 4;
1054  }
1055  else
1056  {
1057  maxbits = 128;
1058  maxbytes = 16;
1059  }
1060  Assert(bits <= maxbits);
1061 
1062  if (bits == maxbits)
1063  return true;
1064 
1065  byte = bits / 8;
1066 
1067  nbits = bits % 8;
1068  mask = 0xff;
1069  if (bits != 0)
1070  mask >>= nbits;
1071 
1072  while (byte < maxbytes)
1073  {
1074  if ((a[byte] & mask) != 0)
1075  return false;
1076  mask = 0xff;
1077  byte++;
1078  }
1079 
1080  return true;
1081 }
1082 
1083 
1084 /*
1085  * These functions are used by planner to generate indexscan limits
1086  * for clauses a << b and a <<= b
1087  */
1088 
1089 /* return the minimal value for an IP on a given network */
1090 Datum
1092 {
1094 }
1095 
1096 /*
1097  * return "last" IP on a given network. It's the broadcast address,
1098  * however, masklen has to be set to its max bits, since
1099  * 192.168.0.255/24 is considered less than 192.168.0.255/32
1100  *
1101  * inet_set_masklen() hacked to max out the masklength to 128 for IPv6
1102  * and 32 for IPv4 when given '-1' as argument.
1103  */
1104 Datum
1106 {
1109  Int32GetDatum(-1));
1110 }
1111 
1112 
1113 /*
1114  * IP address that the client is connecting from (NULL if Unix socket)
1115  */
1116 Datum
1118 {
1119  Port *port = MyProcPort;
1120  char remote_host[NI_MAXHOST];
1121  int ret;
1122 
1123  if (port == NULL)
1124  PG_RETURN_NULL();
1125 
1126  switch (port->raddr.addr.ss_family)
1127  {
1128  case AF_INET:
1129 #ifdef HAVE_IPV6
1130  case AF_INET6:
1131 #endif
1132  break;
1133  default:
1134  PG_RETURN_NULL();
1135  }
1136 
1137  remote_host[0] = '\0';
1138 
1139  ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1140  remote_host, sizeof(remote_host),
1141  NULL, 0,
1143  if (ret != 0)
1144  PG_RETURN_NULL();
1145 
1146  clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
1147 
1148  PG_RETURN_INET_P(network_in(remote_host, false));
1149 }
1150 
1151 
1152 /*
1153  * port that the client is connecting from (NULL if Unix socket)
1154  */
1155 Datum
1157 {
1158  Port *port = MyProcPort;
1159  char remote_port[NI_MAXSERV];
1160  int ret;
1161 
1162  if (port == NULL)
1163  PG_RETURN_NULL();
1164 
1165  switch (port->raddr.addr.ss_family)
1166  {
1167  case AF_INET:
1168 #ifdef HAVE_IPV6
1169  case AF_INET6:
1170 #endif
1171  break;
1172  default:
1173  PG_RETURN_NULL();
1174  }
1175 
1176  remote_port[0] = '\0';
1177 
1178  ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1179  NULL, 0,
1180  remote_port, sizeof(remote_port),
1182  if (ret != 0)
1183  PG_RETURN_NULL();
1184 
1186 }
1187 
1188 
1189 /*
1190  * IP address that the server accepted the connection on (NULL if Unix socket)
1191  */
1192 Datum
1194 {
1195  Port *port = MyProcPort;
1196  char local_host[NI_MAXHOST];
1197  int ret;
1198 
1199  if (port == NULL)
1200  PG_RETURN_NULL();
1201 
1202  switch (port->laddr.addr.ss_family)
1203  {
1204  case AF_INET:
1205 #ifdef HAVE_IPV6
1206  case AF_INET6:
1207 #endif
1208  break;
1209  default:
1210  PG_RETURN_NULL();
1211  }
1212 
1213  local_host[0] = '\0';
1214 
1215  ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1216  local_host, sizeof(local_host),
1217  NULL, 0,
1219  if (ret != 0)
1220  PG_RETURN_NULL();
1221 
1222  clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
1223 
1224  PG_RETURN_INET_P(network_in(local_host, false));
1225 }
1226 
1227 
1228 /*
1229  * port that the server accepted the connection on (NULL if Unix socket)
1230  */
1231 Datum
1233 {
1234  Port *port = MyProcPort;
1235  char local_port[NI_MAXSERV];
1236  int ret;
1237 
1238  if (port == NULL)
1239  PG_RETURN_NULL();
1240 
1241  switch (port->laddr.addr.ss_family)
1242  {
1243  case AF_INET:
1244 #ifdef HAVE_IPV6
1245  case AF_INET6:
1246 #endif
1247  break;
1248  default:
1249  PG_RETURN_NULL();
1250  }
1251 
1252  local_port[0] = '\0';
1253 
1254  ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1255  NULL, 0,
1256  local_port, sizeof(local_port),
1258  if (ret != 0)
1259  PG_RETURN_NULL();
1260 
1262 }
1263 
1264 
1265 Datum
1267 {
1268  inet *ip = PG_GETARG_INET_PP(0);
1269  inet *dst;
1270 
1271  dst = (inet *) palloc0(sizeof(inet));
1272 
1273  {
1274  int nb = ip_addrsize(ip);
1275  unsigned char *pip = ip_addr(ip);
1276  unsigned char *pdst = ip_addr(dst);
1277 
1278  while (nb-- > 0)
1279  pdst[nb] = ~pip[nb];
1280  }
1281  ip_bits(dst) = ip_bits(ip);
1282 
1283  ip_family(dst) = ip_family(ip);
1284  SET_INET_VARSIZE(dst);
1285 
1286  PG_RETURN_INET_P(dst);
1287 }
1288 
1289 
1290 Datum
1292 {
1293  inet *ip = PG_GETARG_INET_PP(0);
1294  inet *ip2 = PG_GETARG_INET_PP(1);
1295  inet *dst;
1296 
1297  dst = (inet *) palloc0(sizeof(inet));
1298 
1299  if (ip_family(ip) != ip_family(ip2))
1300  ereport(ERROR,
1301  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1302  errmsg("cannot AND inet values of different sizes")));
1303  else
1304  {
1305  int nb = ip_addrsize(ip);
1306  unsigned char *pip = ip_addr(ip);
1307  unsigned char *pip2 = ip_addr(ip2);
1308  unsigned char *pdst = ip_addr(dst);
1309 
1310  while (nb-- > 0)
1311  pdst[nb] = pip[nb] & pip2[nb];
1312  }
1313  ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1314 
1315  ip_family(dst) = ip_family(ip);
1316  SET_INET_VARSIZE(dst);
1317 
1318  PG_RETURN_INET_P(dst);
1319 }
1320 
1321 
1322 Datum
1324 {
1325  inet *ip = PG_GETARG_INET_PP(0);
1326  inet *ip2 = PG_GETARG_INET_PP(1);
1327  inet *dst;
1328 
1329  dst = (inet *) palloc0(sizeof(inet));
1330 
1331  if (ip_family(ip) != ip_family(ip2))
1332  ereport(ERROR,
1333  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1334  errmsg("cannot OR inet values of different sizes")));
1335  else
1336  {
1337  int nb = ip_addrsize(ip);
1338  unsigned char *pip = ip_addr(ip);
1339  unsigned char *pip2 = ip_addr(ip2);
1340  unsigned char *pdst = ip_addr(dst);
1341 
1342  while (nb-- > 0)
1343  pdst[nb] = pip[nb] | pip2[nb];
1344  }
1345  ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1346 
1347  ip_family(dst) = ip_family(ip);
1348  SET_INET_VARSIZE(dst);
1349 
1350  PG_RETURN_INET_P(dst);
1351 }
1352 
1353 
1354 static inet *
1355 internal_inetpl(inet *ip, int64 addend)
1356 {
1357  inet *dst;
1358 
1359  dst = (inet *) palloc0(sizeof(inet));
1360 
1361  {
1362  int nb = ip_addrsize(ip);
1363  unsigned char *pip = ip_addr(ip);
1364  unsigned char *pdst = ip_addr(dst);
1365  int carry = 0;
1366 
1367  while (nb-- > 0)
1368  {
1369  carry = pip[nb] + (int) (addend & 0xFF) + carry;
1370  pdst[nb] = (unsigned char) (carry & 0xFF);
1371  carry >>= 8;
1372 
1373  /*
1374  * We have to be careful about right-shifting addend because
1375  * right-shift isn't portable for negative values, while simply
1376  * dividing by 256 doesn't work (the standard rounding is in the
1377  * wrong direction, besides which there may be machines out there
1378  * that round the wrong way). So, explicitly clear the low-order
1379  * byte to remove any doubt about the correct result of the
1380  * division, and then divide rather than shift.
1381  */
1382  addend &= ~((int64) 0xFF);
1383  addend /= 0x100;
1384  }
1385 
1386  /*
1387  * At this point we should have addend and carry both zero if original
1388  * addend was >= 0, or addend -1 and carry 1 if original addend was <
1389  * 0. Anything else means overflow.
1390  */
1391  if (!((addend == 0 && carry == 0) ||
1392  (addend == -1 && carry == 1)))
1393  ereport(ERROR,
1394  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1395  errmsg("result is out of range")));
1396  }
1397 
1398  ip_bits(dst) = ip_bits(ip);
1399  ip_family(dst) = ip_family(ip);
1400  SET_INET_VARSIZE(dst);
1401 
1402  return dst;
1403 }
1404 
1405 
1406 Datum
1408 {
1409  inet *ip = PG_GETARG_INET_PP(0);
1410  int64 addend = PG_GETARG_INT64(1);
1411 
1412  PG_RETURN_INET_P(internal_inetpl(ip, addend));
1413 }
1414 
1415 
1416 Datum
1418 {
1419  inet *ip = PG_GETARG_INET_PP(0);
1420  int64 addend = PG_GETARG_INT64(1);
1421 
1422  PG_RETURN_INET_P(internal_inetpl(ip, -addend));
1423 }
1424 
1425 
1426 Datum
1428 {
1429  inet *ip = PG_GETARG_INET_PP(0);
1430  inet *ip2 = PG_GETARG_INET_PP(1);
1431  int64 res = 0;
1432 
1433  if (ip_family(ip) != ip_family(ip2))
1434  ereport(ERROR,
1435  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1436  errmsg("cannot subtract inet values of different sizes")));
1437  else
1438  {
1439  /*
1440  * We form the difference using the traditional complement, increment,
1441  * and add rule, with the increment part being handled by starting the
1442  * carry off at 1. If you don't think integer arithmetic is done in
1443  * two's complement, too bad.
1444  */
1445  int nb = ip_addrsize(ip);
1446  int byte = 0;
1447  unsigned char *pip = ip_addr(ip);
1448  unsigned char *pip2 = ip_addr(ip2);
1449  int carry = 1;
1450 
1451  while (nb-- > 0)
1452  {
1453  int lobyte;
1454 
1455  carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
1456  lobyte = carry & 0xFF;
1457  if (byte < sizeof(int64))
1458  {
1459  res |= ((int64) lobyte) << (byte * 8);
1460  }
1461  else
1462  {
1463  /*
1464  * Input wider than int64: check for overflow. All bytes to
1465  * the left of what will fit should be 0 or 0xFF, depending on
1466  * sign of the now-complete result.
1467  */
1468  if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
1469  ereport(ERROR,
1470  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1471  errmsg("result is out of range")));
1472  }
1473  carry >>= 8;
1474  byte++;
1475  }
1476 
1477  /*
1478  * If input is narrower than int64, overflow is not possible, but we
1479  * have to do proper sign extension.
1480  */
1481  if (carry == 0 && byte < sizeof(int64))
1482  res |= ((int64) -1) << (byte * 8);
1483  }
1484 
1485  PG_RETURN_INT64(res);
1486 }
1487 
1488 
1489 /*
1490  * clean_ipv6_addr --- remove any '%zone' part from an IPv6 address string
1491  *
1492  * XXX This should go away someday!
1493  *
1494  * This is a kluge needed because we don't yet support zones in stored inet
1495  * values. Since the result of getnameinfo() might include a zone spec,
1496  * call this to remove it anywhere we want to feed getnameinfo's output to
1497  * network_in. Beats failing entirely.
1498  *
1499  * An alternative approach would be to let network_in ignore %-parts for
1500  * itself, but that would mean we'd silently drop zone specs in user input,
1501  * which seems not such a good idea.
1502  */
1503 void
1504 clean_ipv6_addr(int addr_family, char *addr)
1505 {
1506 #ifdef HAVE_IPV6
1507  if (addr_family == AF_INET6)
1508  {
1509  char *pct = strchr(addr, '%');
1510 
1511  if (pct)
1512  *pct = '\0';
1513  }
1514 #endif
1515 }
#define CIDROID
Definition: pg_type.h:451
Datum network_broadcast(PG_FUNCTION_ARGS)
Definition: network.c:683
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
Datum inet_same_family(PG_FUNCTION_ARGS)
Definition: network.c:862
Datum hashinet(PG_FUNCTION_ARGS)
Definition: network.c:480
#define DatumGetMacaddrP(X)
Definition: inet.h:131
#define NI_NUMERICHOST
Definition: getaddrinfo.h:78
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
Datum inetpl(PG_FUNCTION_ARGS)
Definition: network.c:1407
#define ip_bits(inetptr)
Definition: inet.h:74
struct Port * MyProcPort
Definition: globals.c:41
void pq_sendbyte(StringInfo buf, int byt)
Definition: pqformat.c:105
#define ip_family(inetptr)
Definition: inet.h:71
static bool addressOK(unsigned char *a, int bits, int family)
Definition: network.c:1042
#define PGSQL_AF_INET
Definition: inet.h:39
Datum cidr_recv(PG_FUNCTION_ARGS)
Definition: network.c:217
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
Datum network_scan_last(Datum in)
Definition: network.c:1105
#define INETOID
Definition: pg_type.h:448
#define DatumGetInetPP(X)
Definition: inet.h:122
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
char * pstrdup(const char *in)
Definition: mcxt.c:1077
unsigned char f
Definition: inet.h:101
#define ip_addr(inetptr)
Definition: inet.h:77
Datum int4in(PG_FUNCTION_ARGS)
Definition: int.c:266
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define Min(x, y)
Definition: c.h:806
#define SET_INET_VARSIZE(dst)
Definition: inet.h:86
struct sockaddr_storage addr
Definition: pqcomm.h:64
Datum cidr_set_masklen(PG_FUNCTION_ARGS)
Definition: network.c:307
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
Datum cidr_send(PG_FUNCTION_ARGS)
Definition: network.c:259
#define PG_RETURN_INET_P(x)
Definition: inet.h:125
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1004
int errcode(int sqlerrcode)
Definition: elog.c:575
Datum network_family(PG_FUNCTION_ARGS)
Definition: network.c:664
Definition: libpq-be.h:116
Datum cidr_out(PG_FUNCTION_ARGS)
Definition: network.c:132
Datum inet_out(PG_FUNCTION_ARGS)
Definition: network.c:124
Datum network_host(PG_FUNCTION_ARGS)
Definition: network.c:571
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
Datum network_le(PG_FUNCTION_ARGS)
Definition: network.c:405
static inet * network_in(char *src, bool is_cidr)
Definition: network.c:34
#define ip_addrsize(inetptr)
Definition: inet.h:80
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:584
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:329
Datum network_netmask(PG_FUNCTION_ARGS)
Definition: network.c:772
unsigned int Oid
Definition: postgres_ext.h:31
#define PGSQL_AF_INET6
Definition: inet.h:40
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
unsigned char h
Definition: inet.h:116
Datum network_masklen(PG_FUNCTION_ARGS)
Definition: network.c:656
Datum network_ne(PG_FUNCTION_ARGS)
Definition: network.c:441
Datum inet_set_masklen(PG_FUNCTION_ARGS)
Definition: network.c:283
Datum network_lt(PG_FUNCTION_ARGS)
Definition: network.c:396
signed int int32
Definition: c.h:256
unsigned char f
Definition: inet.h:114
unsigned char g
Definition: inet.h:115
#define ip_maxbits(inetptr)
Definition: inet.h:83
SockAddr raddr
Definition: libpq-be.h:122
char * inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
unsigned char c
Definition: inet.h:98
unsigned char a
Definition: inet.h:109
#define NI_MAXHOST
Definition: getaddrinfo.h:88
#define IS_HIGHBIT_SET(ch)
Definition: c.h:973
#define ERROR
Definition: elog.h:43
unsigned char a
Definition: inet.h:96
Definition: inet.h:107
static struct @121 value
double convert_network_to_scalar(Datum value, Oid typid)
Definition: network.c:897
unsigned char d
Definition: inet.h:99
static int32 network_cmp_internal(inet *a1, inet *a2)
Definition: network.c:364
Datum network_show(PG_FUNCTION_ARGS)
Definition: network.c:597
static char * buf
Definition: pg_test_fsync.c:66
unsigned char b
Definition: inet.h:110
#define PG_GETARG_INET_PP(n)
Definition: inet.h:124
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define CStringGetDatum(X)
Definition: postgres.h:584
Definition: inet.h:52
#define NI_MAXSERV
Definition: getaddrinfo.h:91
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
unsigned char e
Definition: inet.h:113
Datum network_smaller(PG_FUNCTION_ARGS)
Definition: network.c:453
static inet * internal_inetpl(inet *ip, int64 addend)
Definition: network.c:1355
int inet_net_pton(int af, const char *src, void *dst, size_t size)
Definition: inet_net_pton.c:62
char * inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
Definition: inet_net_ntop.c:77
#define ereport(elevel, rest)
Definition: elog.h:122
Datum inetmi_int8(PG_FUNCTION_ARGS)
Definition: network.c:1417
SockAddr laddr
Definition: libpq-be.h:121
static int port
Definition: pg_regress.c:89
Datum network_gt(PG_FUNCTION_ARGS)
Definition: network.c:432
#define byte(x, n)
Definition: rijndael.c:68
Datum network_eq(PG_FUNCTION_ARGS)
Definition: network.c:414
Datum network_ge(PG_FUNCTION_ARGS)
Definition: network.c:423
Datum network_scan_first(Datum in)
Definition: network.c:1091
unsigned char c
Definition: inet.h:111
Datum inet_abbrev(PG_FUNCTION_ARGS)
Definition: network.c:620
void * palloc0(Size size)
Definition: mcxt.c:878
Datum cidr_abbrev(PG_FUNCTION_ARGS)
Definition: network.c:638
unsigned char b
Definition: inet.h:97
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:313
unsigned char e
Definition: inet.h:100
Datum network_subeq(PG_FUNCTION_ARGS)
Definition: network.c:508
#define VARSIZE_ANY(PTR)
Definition: postgres.h:334
#define NI_NUMERICSERV
Definition: getaddrinfo.h:81
Datum inet_to_cidr(PG_FUNCTION_ARGS)
Definition: network.c:268
Datum inet_send(PG_FUNCTION_ARGS)
Definition: network.c:251
static FormData_pg_attribute a1
Definition: heap.c:144
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:432
Datum inetmi(PG_FUNCTION_ARGS)
Definition: network.c:1427
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
static bytea * network_send(inet *addr, bool is_cidr)
Definition: network.c:229
#define Max(x, y)
Definition: c.h:800
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define NULL
Definition: c.h:229
Datum network_overlap(PG_FUNCTION_ARGS)
Definition: network.c:553
#define Assert(condition)
Definition: c.h:675
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
Datum hash_any(register const unsigned char *k, register int keylen)
Definition: hashfunc.c:307
Datum inet_in(PG_FUNCTION_ARGS)
Definition: network.c:80
static char * network_out(inet *src, bool is_cidr)
Definition: network.c:100
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
Datum inet_client_addr(PG_FUNCTION_ARGS)
Definition: network.c:1117
void clean_ipv6_addr(int addr_family, char *addr)
Definition: network.c:1504
Datum network_sup(PG_FUNCTION_ARGS)
Definition: network.c:523
inet * cidr_set_masklen_internal(const inet *src, int bits)
Definition: network.c:327
Definition: inet.h:94
Datum inet_recv(PG_FUNCTION_ARGS)
Definition: network.c:209
Datum cidr_in(PG_FUNCTION_ARGS)
Definition: network.c:88
static inet * network_recv(StringInfo buf, bool is_cidr)
Definition: network.c:151
Datum network_hostmask(PG_FUNCTION_ARGS)
Definition: network.c:814
Datum inet_client_port(PG_FUNCTION_ARGS)
Definition: network.c:1156
Datum inetor(PG_FUNCTION_ARGS)
Definition: network.c:1323
Datum inet_server_port(PG_FUNCTION_ARGS)
Definition: network.c:1232
#define Int32GetDatum(X)
Definition: postgres.h:485
#define DatumGetMacaddr8P(X)
Definition: inet.h:137
#define MACADDR8OID
Definition: pg_type.h:454
Datum inetnot(PG_FUNCTION_ARGS)
Definition: network.c:1266
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
unsigned char d
Definition: inet.h:112
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:970
Datum network_larger(PG_FUNCTION_ARGS)
Definition: network.c:465
int i
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
Definition: c.h:439
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
Datum network_sub(PG_FUNCTION_ARGS)
Definition: network.c:493
Datum network_cmp(PG_FUNCTION_ARGS)
Definition: network.c:384
#define MACADDROID
Definition: pg_type.h:445
#define elog
Definition: elog.h:219
Datum network_supeq(PG_FUNCTION_ARGS)
Definition: network.c:538
Datum inet_merge(PG_FUNCTION_ARGS)
Definition: network.c:874
Datum inet_server_addr(PG_FUNCTION_ARGS)
Definition: network.c:1193
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
Datum network_network(PG_FUNCTION_ARGS)
Definition: network.c:728
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:586
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum inetand(PG_FUNCTION_ARGS)
Definition: network.c:1291
static FormData_pg_attribute a2
Definition: heap.c:150