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 
25 static int32 network_cmp_internal(inet *a1, inet *a2);
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 *
network_in(char * src,bool is_cidr)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)
48 		ip_family(dst) = PGSQL_AF_INET6;
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
inet_in(PG_FUNCTION_ARGS)80 inet_in(PG_FUNCTION_ARGS)
81 {
82 	char	   *src = PG_GETARG_CSTRING(0);
83 
84 	PG_RETURN_INET_P(network_in(src, false));
85 }
86 
87 Datum
cidr_in(PG_FUNCTION_ARGS)88 cidr_in(PG_FUNCTION_ARGS)
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 *
network_out(inet * src,bool is_cidr)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
inet_out(PG_FUNCTION_ARGS)124 inet_out(PG_FUNCTION_ARGS)
125 {
126 	inet	   *src = PG_GETARG_INET_PP(0);
127 
128 	PG_RETURN_CSTRING(network_out(src, false));
129 }
130 
131 Datum
cidr_out(PG_FUNCTION_ARGS)132 cidr_out(PG_FUNCTION_ARGS)
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 *
network_recv(StringInfo buf,bool is_cidr)151 network_recv(StringInfo buf, bool is_cidr)
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
inet_recv(PG_FUNCTION_ARGS)209 inet_recv(PG_FUNCTION_ARGS)
210 {
211 	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
212 
213 	PG_RETURN_INET_P(network_recv(buf, false));
214 }
215 
216 Datum
cidr_recv(PG_FUNCTION_ARGS)217 cidr_recv(PG_FUNCTION_ARGS)
218 {
219 	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
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 *
network_send(inet * addr,bool is_cidr)229 network_send(inet *addr, bool is_cidr)
230 {
231 	StringInfoData buf;
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
inet_send(PG_FUNCTION_ARGS)251 inet_send(PG_FUNCTION_ARGS)
252 {
253 	inet	   *addr = PG_GETARG_INET_PP(0);
254 
255 	PG_RETURN_BYTEA_P(network_send(addr, false));
256 }
257 
258 Datum
cidr_send(PG_FUNCTION_ARGS)259 cidr_send(PG_FUNCTION_ARGS)
260 {
261 	inet	   *addr = PG_GETARG_INET_PP(0);
262 
263 	PG_RETURN_BYTEA_P(network_send(addr, true));
264 }
265 
266 
267 Datum
inet_to_cidr(PG_FUNCTION_ARGS)268 inet_to_cidr(PG_FUNCTION_ARGS)
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 
279 	PG_RETURN_INET_P(cidr_set_masklen_internal(src, bits));
280 }
281 
282 Datum
inet_set_masklen(PG_FUNCTION_ARGS)283 inet_set_masklen(PG_FUNCTION_ARGS)
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
cidr_set_masklen(PG_FUNCTION_ARGS)307 cidr_set_masklen(PG_FUNCTION_ARGS)
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 
320 	PG_RETURN_INET_P(cidr_set_masklen_internal(src, bits));
321 }
322 
323 /*
324  * Copy src and set mask length to 'bits' (which must be valid for the family)
325  */
326 inet *
cidr_set_masklen_internal(const inet * src,int bits)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
network_cmp_internal(inet * a1,inet * a2)364 network_cmp_internal(inet *a1, inet *a2)
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
network_cmp(PG_FUNCTION_ARGS)384 network_cmp(PG_FUNCTION_ARGS)
385 {
386 	inet	   *a1 = PG_GETARG_INET_PP(0);
387 	inet	   *a2 = PG_GETARG_INET_PP(1);
388 
389 	PG_RETURN_INT32(network_cmp_internal(a1, a2));
390 }
391 
392 /*
393  *	Boolean ordering tests.
394  */
395 Datum
network_lt(PG_FUNCTION_ARGS)396 network_lt(PG_FUNCTION_ARGS)
397 {
398 	inet	   *a1 = PG_GETARG_INET_PP(0);
399 	inet	   *a2 = PG_GETARG_INET_PP(1);
400 
401 	PG_RETURN_BOOL(network_cmp_internal(a1, a2) < 0);
402 }
403 
404 Datum
network_le(PG_FUNCTION_ARGS)405 network_le(PG_FUNCTION_ARGS)
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
network_eq(PG_FUNCTION_ARGS)414 network_eq(PG_FUNCTION_ARGS)
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
network_ge(PG_FUNCTION_ARGS)423 network_ge(PG_FUNCTION_ARGS)
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
network_gt(PG_FUNCTION_ARGS)432 network_gt(PG_FUNCTION_ARGS)
433 {
434 	inet	   *a1 = PG_GETARG_INET_PP(0);
435 	inet	   *a2 = PG_GETARG_INET_PP(1);
436 
437 	PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0);
438 }
439 
440 Datum
network_ne(PG_FUNCTION_ARGS)441 network_ne(PG_FUNCTION_ARGS)
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
network_smaller(PG_FUNCTION_ARGS)453 network_smaller(PG_FUNCTION_ARGS)
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
network_larger(PG_FUNCTION_ARGS)465 network_larger(PG_FUNCTION_ARGS)
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
hashinet(PG_FUNCTION_ARGS)480 hashinet(PG_FUNCTION_ARGS)
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 Datum
hashinetextended(PG_FUNCTION_ARGS)490 hashinetextended(PG_FUNCTION_ARGS)
491 {
492 	inet	   *addr = PG_GETARG_INET_PP(0);
493 	int			addrsize = ip_addrsize(addr);
494 
495 	return hash_any_extended((unsigned char *) VARDATA_ANY(addr), addrsize + 2,
496 							 PG_GETARG_INT64(1));
497 }
498 
499 /*
500  *	Boolean network-inclusion tests.
501  */
502 Datum
network_sub(PG_FUNCTION_ARGS)503 network_sub(PG_FUNCTION_ARGS)
504 {
505 	inet	   *a1 = PG_GETARG_INET_PP(0);
506 	inet	   *a2 = PG_GETARG_INET_PP(1);
507 
508 	if (ip_family(a1) == ip_family(a2))
509 	{
510 		PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2) &&
511 					   bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
512 	}
513 
514 	PG_RETURN_BOOL(false);
515 }
516 
517 Datum
network_subeq(PG_FUNCTION_ARGS)518 network_subeq(PG_FUNCTION_ARGS)
519 {
520 	inet	   *a1 = PG_GETARG_INET_PP(0);
521 	inet	   *a2 = PG_GETARG_INET_PP(1);
522 
523 	if (ip_family(a1) == ip_family(a2))
524 	{
525 		PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2) &&
526 					   bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
527 	}
528 
529 	PG_RETURN_BOOL(false);
530 }
531 
532 Datum
network_sup(PG_FUNCTION_ARGS)533 network_sup(PG_FUNCTION_ARGS)
534 {
535 	inet	   *a1 = PG_GETARG_INET_PP(0);
536 	inet	   *a2 = PG_GETARG_INET_PP(1);
537 
538 	if (ip_family(a1) == ip_family(a2))
539 	{
540 		PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2) &&
541 					   bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
542 	}
543 
544 	PG_RETURN_BOOL(false);
545 }
546 
547 Datum
network_supeq(PG_FUNCTION_ARGS)548 network_supeq(PG_FUNCTION_ARGS)
549 {
550 	inet	   *a1 = PG_GETARG_INET_PP(0);
551 	inet	   *a2 = PG_GETARG_INET_PP(1);
552 
553 	if (ip_family(a1) == ip_family(a2))
554 	{
555 		PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2) &&
556 					   bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
557 	}
558 
559 	PG_RETURN_BOOL(false);
560 }
561 
562 Datum
network_overlap(PG_FUNCTION_ARGS)563 network_overlap(PG_FUNCTION_ARGS)
564 {
565 	inet	   *a1 = PG_GETARG_INET_PP(0);
566 	inet	   *a2 = PG_GETARG_INET_PP(1);
567 
568 	if (ip_family(a1) == ip_family(a2))
569 	{
570 		PG_RETURN_BOOL(bitncmp(ip_addr(a1), ip_addr(a2),
571 							   Min(ip_bits(a1), ip_bits(a2))) == 0);
572 	}
573 
574 	PG_RETURN_BOOL(false);
575 }
576 
577 /*
578  * Extract data from a network datatype.
579  */
580 Datum
network_host(PG_FUNCTION_ARGS)581 network_host(PG_FUNCTION_ARGS)
582 {
583 	inet	   *ip = PG_GETARG_INET_PP(0);
584 	char	   *ptr;
585 	char		tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
586 
587 	/* force display of max bits, regardless of masklen... */
588 	if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
589 					  tmp, sizeof(tmp)) == NULL)
590 		ereport(ERROR,
591 				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
592 				 errmsg("could not format inet value: %m")));
593 
594 	/* Suppress /n if present (shouldn't happen now) */
595 	if ((ptr = strchr(tmp, '/')) != NULL)
596 		*ptr = '\0';
597 
598 	PG_RETURN_TEXT_P(cstring_to_text(tmp));
599 }
600 
601 /*
602  * network_show implements the inet and cidr casts to text.  This is not
603  * quite the same behavior as network_out, hence we can't drop it in favor
604  * of CoerceViaIO.
605  */
606 Datum
network_show(PG_FUNCTION_ARGS)607 network_show(PG_FUNCTION_ARGS)
608 {
609 	inet	   *ip = PG_GETARG_INET_PP(0);
610 	int			len;
611 	char		tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
612 
613 	if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
614 					  tmp, sizeof(tmp)) == NULL)
615 		ereport(ERROR,
616 				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
617 				 errmsg("could not format inet value: %m")));
618 
619 	/* Add /n if not present (which it won't be) */
620 	if (strchr(tmp, '/') == NULL)
621 	{
622 		len = strlen(tmp);
623 		snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
624 	}
625 
626 	PG_RETURN_TEXT_P(cstring_to_text(tmp));
627 }
628 
629 Datum
inet_abbrev(PG_FUNCTION_ARGS)630 inet_abbrev(PG_FUNCTION_ARGS)
631 {
632 	inet	   *ip = PG_GETARG_INET_PP(0);
633 	char	   *dst;
634 	char		tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
635 
636 	dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
637 						ip_bits(ip), tmp, sizeof(tmp));
638 
639 	if (dst == NULL)
640 		ereport(ERROR,
641 				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
642 				 errmsg("could not format inet value: %m")));
643 
644 	PG_RETURN_TEXT_P(cstring_to_text(tmp));
645 }
646 
647 Datum
cidr_abbrev(PG_FUNCTION_ARGS)648 cidr_abbrev(PG_FUNCTION_ARGS)
649 {
650 	inet	   *ip = PG_GETARG_INET_PP(0);
651 	char	   *dst;
652 	char		tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
653 
654 	dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
655 						 ip_bits(ip), tmp, sizeof(tmp));
656 
657 	if (dst == NULL)
658 		ereport(ERROR,
659 				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
660 				 errmsg("could not format cidr value: %m")));
661 
662 	PG_RETURN_TEXT_P(cstring_to_text(tmp));
663 }
664 
665 Datum
network_masklen(PG_FUNCTION_ARGS)666 network_masklen(PG_FUNCTION_ARGS)
667 {
668 	inet	   *ip = PG_GETARG_INET_PP(0);
669 
670 	PG_RETURN_INT32(ip_bits(ip));
671 }
672 
673 Datum
network_family(PG_FUNCTION_ARGS)674 network_family(PG_FUNCTION_ARGS)
675 {
676 	inet	   *ip = PG_GETARG_INET_PP(0);
677 
678 	switch (ip_family(ip))
679 	{
680 		case PGSQL_AF_INET:
681 			PG_RETURN_INT32(4);
682 			break;
683 		case PGSQL_AF_INET6:
684 			PG_RETURN_INT32(6);
685 			break;
686 		default:
687 			PG_RETURN_INT32(0);
688 			break;
689 	}
690 }
691 
692 Datum
network_broadcast(PG_FUNCTION_ARGS)693 network_broadcast(PG_FUNCTION_ARGS)
694 {
695 	inet	   *ip = PG_GETARG_INET_PP(0);
696 	inet	   *dst;
697 	int			byte;
698 	int			bits;
699 	int			maxbytes;
700 	unsigned char mask;
701 	unsigned char *a,
702 			   *b;
703 
704 	/* make sure any unused bits are zeroed */
705 	dst = (inet *) palloc0(sizeof(inet));
706 
707 	maxbytes = ip_addrsize(ip);
708 	bits = ip_bits(ip);
709 	a = ip_addr(ip);
710 	b = ip_addr(dst);
711 
712 	for (byte = 0; byte < maxbytes; byte++)
713 	{
714 		if (bits >= 8)
715 		{
716 			mask = 0x00;
717 			bits -= 8;
718 		}
719 		else if (bits == 0)
720 			mask = 0xff;
721 		else
722 		{
723 			mask = 0xff >> bits;
724 			bits = 0;
725 		}
726 
727 		b[byte] = a[byte] | mask;
728 	}
729 
730 	ip_family(dst) = ip_family(ip);
731 	ip_bits(dst) = ip_bits(ip);
732 	SET_INET_VARSIZE(dst);
733 
734 	PG_RETURN_INET_P(dst);
735 }
736 
737 Datum
network_network(PG_FUNCTION_ARGS)738 network_network(PG_FUNCTION_ARGS)
739 {
740 	inet	   *ip = PG_GETARG_INET_PP(0);
741 	inet	   *dst;
742 	int			byte;
743 	int			bits;
744 	unsigned char mask;
745 	unsigned char *a,
746 			   *b;
747 
748 	/* make sure any unused bits are zeroed */
749 	dst = (inet *) palloc0(sizeof(inet));
750 
751 	bits = ip_bits(ip);
752 	a = ip_addr(ip);
753 	b = ip_addr(dst);
754 
755 	byte = 0;
756 
757 	while (bits)
758 	{
759 		if (bits >= 8)
760 		{
761 			mask = 0xff;
762 			bits -= 8;
763 		}
764 		else
765 		{
766 			mask = 0xff << (8 - bits);
767 			bits = 0;
768 		}
769 
770 		b[byte] = a[byte] & mask;
771 		byte++;
772 	}
773 
774 	ip_family(dst) = ip_family(ip);
775 	ip_bits(dst) = ip_bits(ip);
776 	SET_INET_VARSIZE(dst);
777 
778 	PG_RETURN_INET_P(dst);
779 }
780 
781 Datum
network_netmask(PG_FUNCTION_ARGS)782 network_netmask(PG_FUNCTION_ARGS)
783 {
784 	inet	   *ip = PG_GETARG_INET_PP(0);
785 	inet	   *dst;
786 	int			byte;
787 	int			bits;
788 	unsigned char mask;
789 	unsigned char *b;
790 
791 	/* make sure any unused bits are zeroed */
792 	dst = (inet *) palloc0(sizeof(inet));
793 
794 	bits = ip_bits(ip);
795 	b = ip_addr(dst);
796 
797 	byte = 0;
798 
799 	while (bits)
800 	{
801 		if (bits >= 8)
802 		{
803 			mask = 0xff;
804 			bits -= 8;
805 		}
806 		else
807 		{
808 			mask = 0xff << (8 - bits);
809 			bits = 0;
810 		}
811 
812 		b[byte] = mask;
813 		byte++;
814 	}
815 
816 	ip_family(dst) = ip_family(ip);
817 	ip_bits(dst) = ip_maxbits(ip);
818 	SET_INET_VARSIZE(dst);
819 
820 	PG_RETURN_INET_P(dst);
821 }
822 
823 Datum
network_hostmask(PG_FUNCTION_ARGS)824 network_hostmask(PG_FUNCTION_ARGS)
825 {
826 	inet	   *ip = PG_GETARG_INET_PP(0);
827 	inet	   *dst;
828 	int			byte;
829 	int			bits;
830 	int			maxbytes;
831 	unsigned char mask;
832 	unsigned char *b;
833 
834 	/* make sure any unused bits are zeroed */
835 	dst = (inet *) palloc0(sizeof(inet));
836 
837 	maxbytes = ip_addrsize(ip);
838 	bits = ip_maxbits(ip) - ip_bits(ip);
839 	b = ip_addr(dst);
840 
841 	byte = maxbytes - 1;
842 
843 	while (bits)
844 	{
845 		if (bits >= 8)
846 		{
847 			mask = 0xff;
848 			bits -= 8;
849 		}
850 		else
851 		{
852 			mask = 0xff >> (8 - bits);
853 			bits = 0;
854 		}
855 
856 		b[byte] = mask;
857 		byte--;
858 	}
859 
860 	ip_family(dst) = ip_family(ip);
861 	ip_bits(dst) = ip_maxbits(ip);
862 	SET_INET_VARSIZE(dst);
863 
864 	PG_RETURN_INET_P(dst);
865 }
866 
867 /*
868  * Returns true if the addresses are from the same family, or false.  Used to
869  * check that we can create a network which contains both of the networks.
870  */
871 Datum
inet_same_family(PG_FUNCTION_ARGS)872 inet_same_family(PG_FUNCTION_ARGS)
873 {
874 	inet	   *a1 = PG_GETARG_INET_PP(0);
875 	inet	   *a2 = PG_GETARG_INET_PP(1);
876 
877 	PG_RETURN_BOOL(ip_family(a1) == ip_family(a2));
878 }
879 
880 /*
881  * Returns the smallest CIDR which contains both of the inputs.
882  */
883 Datum
inet_merge(PG_FUNCTION_ARGS)884 inet_merge(PG_FUNCTION_ARGS)
885 {
886 	inet	   *a1 = PG_GETARG_INET_PP(0),
887 			   *a2 = PG_GETARG_INET_PP(1);
888 	int			commonbits;
889 
890 	if (ip_family(a1) != ip_family(a2))
891 		ereport(ERROR,
892 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
893 				 errmsg("cannot merge addresses from different families")));
894 
895 	commonbits = bitncommon(ip_addr(a1), ip_addr(a2),
896 							Min(ip_bits(a1), ip_bits(a2)));
897 
898 	PG_RETURN_INET_P(cidr_set_masklen_internal(a1, commonbits));
899 }
900 
901 /*
902  * Convert a value of a network datatype to an approximate scalar value.
903  * This is used for estimating selectivities of inequality operators
904  * involving network types.
905  *
906  * On failure (e.g., unsupported typid), set *failure to true;
907  * otherwise, that variable is not changed.
908  */
909 double
convert_network_to_scalar(Datum value,Oid typid,bool * failure)910 convert_network_to_scalar(Datum value, Oid typid, bool *failure)
911 {
912 	switch (typid)
913 	{
914 		case INETOID:
915 		case CIDROID:
916 			{
917 				inet	   *ip = DatumGetInetPP(value);
918 				int			len;
919 				double		res;
920 				int			i;
921 
922 				/*
923 				 * Note that we don't use the full address for IPv6.
924 				 */
925 				if (ip_family(ip) == PGSQL_AF_INET)
926 					len = 4;
927 				else
928 					len = 5;
929 
930 				res = ip_family(ip);
931 				for (i = 0; i < len; i++)
932 				{
933 					res *= 256;
934 					res += ip_addr(ip)[i];
935 				}
936 				return res;
937 			}
938 		case MACADDROID:
939 			{
940 				macaddr    *mac = DatumGetMacaddrP(value);
941 				double		res;
942 
943 				res = (mac->a << 16) | (mac->b << 8) | (mac->c);
944 				res *= 256 * 256 * 256;
945 				res += (mac->d << 16) | (mac->e << 8) | (mac->f);
946 				return res;
947 			}
948 		case MACADDR8OID:
949 			{
950 				macaddr8   *mac = DatumGetMacaddr8P(value);
951 				double		res;
952 
953 				res = (mac->a << 24) | (mac->b << 16) | (mac->c << 8) | (mac->d);
954 				res *= ((double) 256) * 256 * 256 * 256;
955 				res += (mac->e << 24) | (mac->f << 16) | (mac->g << 8) | (mac->h);
956 				return res;
957 			}
958 	}
959 
960 	*failure = true;
961 	return 0;
962 }
963 
964 /*
965  * int
966  * bitncmp(l, r, n)
967  *		compare bit masks l and r, for n bits.
968  * return:
969  *		<0, >0, or 0 in the libc tradition.
970  * note:
971  *		network byte order assumed.  this means 192.5.5.240/28 has
972  *		0x11110000 in its fourth octet.
973  * author:
974  *		Paul Vixie (ISC), June 1996
975  */
976 int
bitncmp(const unsigned char * l,const unsigned char * r,int n)977 bitncmp(const unsigned char *l, const unsigned char *r, int n)
978 {
979 	unsigned int lb,
980 				rb;
981 	int			x,
982 				b;
983 
984 	b = n / 8;
985 	x = memcmp(l, r, b);
986 	if (x || (n % 8) == 0)
987 		return x;
988 
989 	lb = l[b];
990 	rb = r[b];
991 	for (b = n % 8; b > 0; b--)
992 	{
993 		if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
994 		{
995 			if (IS_HIGHBIT_SET(lb))
996 				return 1;
997 			return -1;
998 		}
999 		lb <<= 1;
1000 		rb <<= 1;
1001 	}
1002 	return 0;
1003 }
1004 
1005 /*
1006  * bitncommon: compare bit masks l and r, for up to n bits.
1007  *
1008  * Returns the number of leading bits that match (0 to n).
1009  */
1010 int
bitncommon(const unsigned char * l,const unsigned char * r,int n)1011 bitncommon(const unsigned char *l, const unsigned char *r, int n)
1012 {
1013 	int			byte,
1014 				nbits;
1015 
1016 	/* number of bits to examine in last byte */
1017 	nbits = n % 8;
1018 
1019 	/* check whole bytes */
1020 	for (byte = 0; byte < n / 8; byte++)
1021 	{
1022 		if (l[byte] != r[byte])
1023 		{
1024 			/* at least one bit in the last byte is not common */
1025 			nbits = 7;
1026 			break;
1027 		}
1028 	}
1029 
1030 	/* check bits in last partial byte */
1031 	if (nbits != 0)
1032 	{
1033 		/* calculate diff of first non-matching bytes */
1034 		unsigned int diff = l[byte] ^ r[byte];
1035 
1036 		/* compare the bits from the most to the least */
1037 		while ((diff >> (8 - nbits)) != 0)
1038 			nbits--;
1039 	}
1040 
1041 	return (8 * byte) + nbits;
1042 }
1043 
1044 
1045 /*
1046  * Verify a CIDR address is OK (doesn't have bits set past the masklen)
1047  */
1048 static bool
addressOK(unsigned char * a,int bits,int family)1049 addressOK(unsigned char *a, int bits, int family)
1050 {
1051 	int			byte;
1052 	int			nbits;
1053 	int			maxbits;
1054 	int			maxbytes;
1055 	unsigned char mask;
1056 
1057 	if (family == PGSQL_AF_INET)
1058 	{
1059 		maxbits = 32;
1060 		maxbytes = 4;
1061 	}
1062 	else
1063 	{
1064 		maxbits = 128;
1065 		maxbytes = 16;
1066 	}
1067 	Assert(bits <= maxbits);
1068 
1069 	if (bits == maxbits)
1070 		return true;
1071 
1072 	byte = bits / 8;
1073 
1074 	nbits = bits % 8;
1075 	mask = 0xff;
1076 	if (bits != 0)
1077 		mask >>= nbits;
1078 
1079 	while (byte < maxbytes)
1080 	{
1081 		if ((a[byte] & mask) != 0)
1082 			return false;
1083 		mask = 0xff;
1084 		byte++;
1085 	}
1086 
1087 	return true;
1088 }
1089 
1090 
1091 /*
1092  * These functions are used by planner to generate indexscan limits
1093  * for clauses a << b and a <<= b
1094  */
1095 
1096 /* return the minimal value for an IP on a given network */
1097 Datum
network_scan_first(Datum in)1098 network_scan_first(Datum in)
1099 {
1100 	return DirectFunctionCall1(network_network, in);
1101 }
1102 
1103 /*
1104  * return "last" IP on a given network. It's the broadcast address,
1105  * however, masklen has to be set to its max bits, since
1106  * 192.168.0.255/24 is considered less than 192.168.0.255/32
1107  *
1108  * inet_set_masklen() hacked to max out the masklength to 128 for IPv6
1109  * and 32 for IPv4 when given '-1' as argument.
1110  */
1111 Datum
network_scan_last(Datum in)1112 network_scan_last(Datum in)
1113 {
1114 	return DirectFunctionCall2(inet_set_masklen,
1115 							   DirectFunctionCall1(network_broadcast, in),
1116 							   Int32GetDatum(-1));
1117 }
1118 
1119 
1120 /*
1121  * IP address that the client is connecting from (NULL if Unix socket)
1122  */
1123 Datum
inet_client_addr(PG_FUNCTION_ARGS)1124 inet_client_addr(PG_FUNCTION_ARGS)
1125 {
1126 	Port	   *port = MyProcPort;
1127 	char		remote_host[NI_MAXHOST];
1128 	int			ret;
1129 
1130 	if (port == NULL)
1131 		PG_RETURN_NULL();
1132 
1133 	switch (port->raddr.addr.ss_family)
1134 	{
1135 		case AF_INET:
1136 #ifdef HAVE_IPV6
1137 		case AF_INET6:
1138 #endif
1139 			break;
1140 		default:
1141 			PG_RETURN_NULL();
1142 	}
1143 
1144 	remote_host[0] = '\0';
1145 
1146 	ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1147 							 remote_host, sizeof(remote_host),
1148 							 NULL, 0,
1149 							 NI_NUMERICHOST | NI_NUMERICSERV);
1150 	if (ret != 0)
1151 		PG_RETURN_NULL();
1152 
1153 	clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
1154 
1155 	PG_RETURN_INET_P(network_in(remote_host, false));
1156 }
1157 
1158 
1159 /*
1160  * port that the client is connecting from (NULL if Unix socket)
1161  */
1162 Datum
inet_client_port(PG_FUNCTION_ARGS)1163 inet_client_port(PG_FUNCTION_ARGS)
1164 {
1165 	Port	   *port = MyProcPort;
1166 	char		remote_port[NI_MAXSERV];
1167 	int			ret;
1168 
1169 	if (port == NULL)
1170 		PG_RETURN_NULL();
1171 
1172 	switch (port->raddr.addr.ss_family)
1173 	{
1174 		case AF_INET:
1175 #ifdef HAVE_IPV6
1176 		case AF_INET6:
1177 #endif
1178 			break;
1179 		default:
1180 			PG_RETURN_NULL();
1181 	}
1182 
1183 	remote_port[0] = '\0';
1184 
1185 	ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1186 							 NULL, 0,
1187 							 remote_port, sizeof(remote_port),
1188 							 NI_NUMERICHOST | NI_NUMERICSERV);
1189 	if (ret != 0)
1190 		PG_RETURN_NULL();
1191 
1192 	PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
1193 }
1194 
1195 
1196 /*
1197  * IP address that the server accepted the connection on (NULL if Unix socket)
1198  */
1199 Datum
inet_server_addr(PG_FUNCTION_ARGS)1200 inet_server_addr(PG_FUNCTION_ARGS)
1201 {
1202 	Port	   *port = MyProcPort;
1203 	char		local_host[NI_MAXHOST];
1204 	int			ret;
1205 
1206 	if (port == NULL)
1207 		PG_RETURN_NULL();
1208 
1209 	switch (port->laddr.addr.ss_family)
1210 	{
1211 		case AF_INET:
1212 #ifdef HAVE_IPV6
1213 		case AF_INET6:
1214 #endif
1215 			break;
1216 		default:
1217 			PG_RETURN_NULL();
1218 	}
1219 
1220 	local_host[0] = '\0';
1221 
1222 	ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1223 							 local_host, sizeof(local_host),
1224 							 NULL, 0,
1225 							 NI_NUMERICHOST | NI_NUMERICSERV);
1226 	if (ret != 0)
1227 		PG_RETURN_NULL();
1228 
1229 	clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
1230 
1231 	PG_RETURN_INET_P(network_in(local_host, false));
1232 }
1233 
1234 
1235 /*
1236  * port that the server accepted the connection on (NULL if Unix socket)
1237  */
1238 Datum
inet_server_port(PG_FUNCTION_ARGS)1239 inet_server_port(PG_FUNCTION_ARGS)
1240 {
1241 	Port	   *port = MyProcPort;
1242 	char		local_port[NI_MAXSERV];
1243 	int			ret;
1244 
1245 	if (port == NULL)
1246 		PG_RETURN_NULL();
1247 
1248 	switch (port->laddr.addr.ss_family)
1249 	{
1250 		case AF_INET:
1251 #ifdef HAVE_IPV6
1252 		case AF_INET6:
1253 #endif
1254 			break;
1255 		default:
1256 			PG_RETURN_NULL();
1257 	}
1258 
1259 	local_port[0] = '\0';
1260 
1261 	ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1262 							 NULL, 0,
1263 							 local_port, sizeof(local_port),
1264 							 NI_NUMERICHOST | NI_NUMERICSERV);
1265 	if (ret != 0)
1266 		PG_RETURN_NULL();
1267 
1268 	PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));
1269 }
1270 
1271 
1272 Datum
inetnot(PG_FUNCTION_ARGS)1273 inetnot(PG_FUNCTION_ARGS)
1274 {
1275 	inet	   *ip = PG_GETARG_INET_PP(0);
1276 	inet	   *dst;
1277 
1278 	dst = (inet *) palloc0(sizeof(inet));
1279 
1280 	{
1281 		int			nb = ip_addrsize(ip);
1282 		unsigned char *pip = ip_addr(ip);
1283 		unsigned char *pdst = ip_addr(dst);
1284 
1285 		while (nb-- > 0)
1286 			pdst[nb] = ~pip[nb];
1287 	}
1288 	ip_bits(dst) = ip_bits(ip);
1289 
1290 	ip_family(dst) = ip_family(ip);
1291 	SET_INET_VARSIZE(dst);
1292 
1293 	PG_RETURN_INET_P(dst);
1294 }
1295 
1296 
1297 Datum
inetand(PG_FUNCTION_ARGS)1298 inetand(PG_FUNCTION_ARGS)
1299 {
1300 	inet	   *ip = PG_GETARG_INET_PP(0);
1301 	inet	   *ip2 = PG_GETARG_INET_PP(1);
1302 	inet	   *dst;
1303 
1304 	dst = (inet *) palloc0(sizeof(inet));
1305 
1306 	if (ip_family(ip) != ip_family(ip2))
1307 		ereport(ERROR,
1308 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1309 				 errmsg("cannot AND inet values of different sizes")));
1310 	else
1311 	{
1312 		int			nb = ip_addrsize(ip);
1313 		unsigned char *pip = ip_addr(ip);
1314 		unsigned char *pip2 = ip_addr(ip2);
1315 		unsigned char *pdst = ip_addr(dst);
1316 
1317 		while (nb-- > 0)
1318 			pdst[nb] = pip[nb] & pip2[nb];
1319 	}
1320 	ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1321 
1322 	ip_family(dst) = ip_family(ip);
1323 	SET_INET_VARSIZE(dst);
1324 
1325 	PG_RETURN_INET_P(dst);
1326 }
1327 
1328 
1329 Datum
inetor(PG_FUNCTION_ARGS)1330 inetor(PG_FUNCTION_ARGS)
1331 {
1332 	inet	   *ip = PG_GETARG_INET_PP(0);
1333 	inet	   *ip2 = PG_GETARG_INET_PP(1);
1334 	inet	   *dst;
1335 
1336 	dst = (inet *) palloc0(sizeof(inet));
1337 
1338 	if (ip_family(ip) != ip_family(ip2))
1339 		ereport(ERROR,
1340 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1341 				 errmsg("cannot OR inet values of different sizes")));
1342 	else
1343 	{
1344 		int			nb = ip_addrsize(ip);
1345 		unsigned char *pip = ip_addr(ip);
1346 		unsigned char *pip2 = ip_addr(ip2);
1347 		unsigned char *pdst = ip_addr(dst);
1348 
1349 		while (nb-- > 0)
1350 			pdst[nb] = pip[nb] | pip2[nb];
1351 	}
1352 	ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1353 
1354 	ip_family(dst) = ip_family(ip);
1355 	SET_INET_VARSIZE(dst);
1356 
1357 	PG_RETURN_INET_P(dst);
1358 }
1359 
1360 
1361 static inet *
internal_inetpl(inet * ip,int64 addend)1362 internal_inetpl(inet *ip, int64 addend)
1363 {
1364 	inet	   *dst;
1365 
1366 	dst = (inet *) palloc0(sizeof(inet));
1367 
1368 	{
1369 		int			nb = ip_addrsize(ip);
1370 		unsigned char *pip = ip_addr(ip);
1371 		unsigned char *pdst = ip_addr(dst);
1372 		int			carry = 0;
1373 
1374 		while (nb-- > 0)
1375 		{
1376 			carry = pip[nb] + (int) (addend & 0xFF) + carry;
1377 			pdst[nb] = (unsigned char) (carry & 0xFF);
1378 			carry >>= 8;
1379 
1380 			/*
1381 			 * We have to be careful about right-shifting addend because
1382 			 * right-shift isn't portable for negative values, while simply
1383 			 * dividing by 256 doesn't work (the standard rounding is in the
1384 			 * wrong direction, besides which there may be machines out there
1385 			 * that round the wrong way).  So, explicitly clear the low-order
1386 			 * byte to remove any doubt about the correct result of the
1387 			 * division, and then divide rather than shift.
1388 			 */
1389 			addend &= ~((int64) 0xFF);
1390 			addend /= 0x100;
1391 		}
1392 
1393 		/*
1394 		 * At this point we should have addend and carry both zero if original
1395 		 * addend was >= 0, or addend -1 and carry 1 if original addend was <
1396 		 * 0.  Anything else means overflow.
1397 		 */
1398 		if (!((addend == 0 && carry == 0) ||
1399 			  (addend == -1 && carry == 1)))
1400 			ereport(ERROR,
1401 					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1402 					 errmsg("result is out of range")));
1403 	}
1404 
1405 	ip_bits(dst) = ip_bits(ip);
1406 	ip_family(dst) = ip_family(ip);
1407 	SET_INET_VARSIZE(dst);
1408 
1409 	return dst;
1410 }
1411 
1412 
1413 Datum
inetpl(PG_FUNCTION_ARGS)1414 inetpl(PG_FUNCTION_ARGS)
1415 {
1416 	inet	   *ip = PG_GETARG_INET_PP(0);
1417 	int64		addend = PG_GETARG_INT64(1);
1418 
1419 	PG_RETURN_INET_P(internal_inetpl(ip, addend));
1420 }
1421 
1422 
1423 Datum
inetmi_int8(PG_FUNCTION_ARGS)1424 inetmi_int8(PG_FUNCTION_ARGS)
1425 {
1426 	inet	   *ip = PG_GETARG_INET_PP(0);
1427 	int64		addend = PG_GETARG_INT64(1);
1428 
1429 	PG_RETURN_INET_P(internal_inetpl(ip, -addend));
1430 }
1431 
1432 
1433 Datum
inetmi(PG_FUNCTION_ARGS)1434 inetmi(PG_FUNCTION_ARGS)
1435 {
1436 	inet	   *ip = PG_GETARG_INET_PP(0);
1437 	inet	   *ip2 = PG_GETARG_INET_PP(1);
1438 	int64		res = 0;
1439 
1440 	if (ip_family(ip) != ip_family(ip2))
1441 		ereport(ERROR,
1442 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1443 				 errmsg("cannot subtract inet values of different sizes")));
1444 	else
1445 	{
1446 		/*
1447 		 * We form the difference using the traditional complement, increment,
1448 		 * and add rule, with the increment part being handled by starting the
1449 		 * carry off at 1.  If you don't think integer arithmetic is done in
1450 		 * two's complement, too bad.
1451 		 */
1452 		int			nb = ip_addrsize(ip);
1453 		int			byte = 0;
1454 		unsigned char *pip = ip_addr(ip);
1455 		unsigned char *pip2 = ip_addr(ip2);
1456 		int			carry = 1;
1457 
1458 		while (nb-- > 0)
1459 		{
1460 			int			lobyte;
1461 
1462 			carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
1463 			lobyte = carry & 0xFF;
1464 			if (byte < sizeof(int64))
1465 			{
1466 				res |= ((int64) lobyte) << (byte * 8);
1467 			}
1468 			else
1469 			{
1470 				/*
1471 				 * Input wider than int64: check for overflow.  All bytes to
1472 				 * the left of what will fit should be 0 or 0xFF, depending on
1473 				 * sign of the now-complete result.
1474 				 */
1475 				if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
1476 					ereport(ERROR,
1477 							(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1478 							 errmsg("result is out of range")));
1479 			}
1480 			carry >>= 8;
1481 			byte++;
1482 		}
1483 
1484 		/*
1485 		 * If input is narrower than int64, overflow is not possible, but we
1486 		 * have to do proper sign extension.
1487 		 */
1488 		if (carry == 0 && byte < sizeof(int64))
1489 			res |= ((uint64) (int64) -1) << (byte * 8);
1490 	}
1491 
1492 	PG_RETURN_INT64(res);
1493 }
1494 
1495 
1496 /*
1497  * clean_ipv6_addr --- remove any '%zone' part from an IPv6 address string
1498  *
1499  * XXX This should go away someday!
1500  *
1501  * This is a kluge needed because we don't yet support zones in stored inet
1502  * values.  Since the result of getnameinfo() might include a zone spec,
1503  * call this to remove it anywhere we want to feed getnameinfo's output to
1504  * network_in.  Beats failing entirely.
1505  *
1506  * An alternative approach would be to let network_in ignore %-parts for
1507  * itself, but that would mean we'd silently drop zone specs in user input,
1508  * which seems not such a good idea.
1509  */
1510 void
clean_ipv6_addr(int addr_family,char * addr)1511 clean_ipv6_addr(int addr_family, char *addr)
1512 {
1513 #ifdef HAVE_IPV6
1514 	if (addr_family == AF_INET6)
1515 	{
1516 		char	   *pct = strchr(addr, '%');
1517 
1518 		if (pct)
1519 			*pct = '\0';
1520 	}
1521 #endif
1522 }
1523