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