📄 network.c
字号:
inet *a2 = PG_GETARG_INET_P(1); PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0);}Datumnetwork_gt(PG_FUNCTION_ARGS){ inet *a1 = PG_GETARG_INET_P(0); inet *a2 = PG_GETARG_INET_P(1); PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0);}Datumnetwork_ne(PG_FUNCTION_ARGS){ inet *a1 = PG_GETARG_INET_P(0); inet *a2 = PG_GETARG_INET_P(1); PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);}/* * Support function for hash indexes on inet/cidr. */Datumhashinet(PG_FUNCTION_ARGS){ inet *addr = PG_GETARG_INET_P(0); int addrsize = ip_addrsize(addr); /* XXX this assumes there are no pad bytes in the data structure */ return hash_any((unsigned char *) VARDATA_ANY(addr), addrsize + 2);}/* * Boolean network-inclusion tests. */Datumnetwork_sub(PG_FUNCTION_ARGS){ inet *a1 = PG_GETARG_INET_P(0); inet *a2 = PG_GETARG_INET_P(1); if (ip_family(a1) == ip_family(a2)) { PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2) && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0); } PG_RETURN_BOOL(false);}Datumnetwork_subeq(PG_FUNCTION_ARGS){ inet *a1 = PG_GETARG_INET_P(0); inet *a2 = PG_GETARG_INET_P(1); if (ip_family(a1) == ip_family(a2)) { PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2) && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0); } PG_RETURN_BOOL(false);}Datumnetwork_sup(PG_FUNCTION_ARGS){ inet *a1 = PG_GETARG_INET_P(0); inet *a2 = PG_GETARG_INET_P(1); if (ip_family(a1) == ip_family(a2)) { PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2) && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0); } PG_RETURN_BOOL(false);}Datumnetwork_supeq(PG_FUNCTION_ARGS){ inet *a1 = PG_GETARG_INET_P(0); inet *a2 = PG_GETARG_INET_P(1); if (ip_family(a1) == ip_family(a2)) { PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2) && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0); } PG_RETURN_BOOL(false);}/* * Extract data from a network datatype. */Datumnetwork_host(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); text *ret; int len; char *ptr; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; /* force display of max bits, regardless of masklen... */ if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip), tmp, sizeof(tmp)) == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("could not format inet value: %m"))); /* Suppress /n if present (shouldn't happen now) */ if ((ptr = strchr(tmp, '/')) != NULL) *ptr = '\0'; /* Return string as a text datum */ len = strlen(tmp); ret = (text *) palloc(len + VARHDRSZ); SET_VARSIZE(ret, len + VARHDRSZ); memcpy(VARDATA(ret), tmp, len); PG_RETURN_TEXT_P(ret);}/* * network_show implements the inet and cidr casts to text. This is not * quite the same behavior as network_out, hence we can't drop it in favor * of CoerceViaIO. */Datumnetwork_show(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); text *ret; int len; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip), tmp, sizeof(tmp)) == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("could not format inet value: %m"))); /* Add /n if not present (which it won't be) */ if (strchr(tmp, '/') == NULL) { len = strlen(tmp); snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip)); } /* Return string as a text datum */ len = strlen(tmp); ret = (text *) palloc(len + VARHDRSZ); SET_VARSIZE(ret, len + VARHDRSZ); memcpy(VARDATA(ret), tmp, len); PG_RETURN_TEXT_P(ret);}Datuminet_abbrev(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); text *ret; char *dst; int len; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; dst = inet_net_ntop(ip_family(ip), ip_addr(ip), ip_bits(ip), tmp, sizeof(tmp)); if (dst == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("could not format inet value: %m"))); /* Return string as a text datum */ len = strlen(tmp); ret = (text *) palloc(len + VARHDRSZ); SET_VARSIZE(ret, len + VARHDRSZ); memcpy(VARDATA(ret), tmp, len); PG_RETURN_TEXT_P(ret);}Datumcidr_abbrev(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); text *ret; char *dst; int len; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip), ip_bits(ip), tmp, sizeof(tmp)); if (dst == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("could not format cidr value: %m"))); /* Return string as a text datum */ len = strlen(tmp); ret = (text *) palloc(len + VARHDRSZ); SET_VARSIZE(ret, len + VARHDRSZ); memcpy(VARDATA(ret), tmp, len); PG_RETURN_TEXT_P(ret);}Datumnetwork_masklen(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); PG_RETURN_INT32(ip_bits(ip));}Datumnetwork_family(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); switch (ip_family(ip)) { case PGSQL_AF_INET: PG_RETURN_INT32(4); break; case PGSQL_AF_INET6: PG_RETURN_INT32(6); break; default: PG_RETURN_INT32(0); break; }}Datumnetwork_broadcast(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); inet *dst; int byte; int bits; int maxbytes; unsigned char mask; unsigned char *a, *b; /* make sure any unused bits are zeroed */ dst = (inet *) palloc0(sizeof(inet)); if (ip_family(ip) == PGSQL_AF_INET) maxbytes = 4; else maxbytes = 16; bits = ip_bits(ip); a = ip_addr(ip); b = ip_addr(dst); for (byte = 0; byte < maxbytes; byte++) { if (bits >= 8) { mask = 0x00; bits -= 8; } else if (bits == 0) mask = 0xff; else { mask = 0xff >> bits; bits = 0; } b[byte] = a[byte] | mask; } ip_family(dst) = ip_family(ip); ip_bits(dst) = ip_bits(ip); SET_INET_VARSIZE(dst); PG_RETURN_INET_P(dst);}Datumnetwork_network(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); inet *dst; int byte; int bits; unsigned char mask; unsigned char *a, *b; /* make sure any unused bits are zeroed */ dst = (inet *) palloc0(sizeof(inet)); bits = ip_bits(ip); a = ip_addr(ip); b = ip_addr(dst); byte = 0; while (bits) { if (bits >= 8) { mask = 0xff; bits -= 8; } else { mask = 0xff << (8 - bits); bits = 0; } b[byte] = a[byte] & mask; byte++; } ip_family(dst) = ip_family(ip); ip_bits(dst) = ip_bits(ip); SET_INET_VARSIZE(dst); PG_RETURN_INET_P(dst);}Datumnetwork_netmask(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); inet *dst; int byte; int bits; unsigned char mask; unsigned char *b; /* make sure any unused bits are zeroed */ dst = (inet *) palloc0(sizeof(inet)); bits = ip_bits(ip); b = ip_addr(dst); byte = 0; while (bits) { if (bits >= 8) { mask = 0xff; bits -= 8; } else { mask = 0xff << (8 - bits); bits = 0; } b[byte] = mask; byte++; } ip_family(dst) = ip_family(ip); ip_bits(dst) = ip_maxbits(ip); SET_INET_VARSIZE(dst); PG_RETURN_INET_P(dst);}Datumnetwork_hostmask(PG_FUNCTION_ARGS){ inet *ip = PG_GETARG_INET_P(0); inet *dst; int byte; int bits; int maxbytes; unsigned char mask; unsigned char *b; /* make sure any unused bits are zeroed */ dst = (inet *) palloc0(sizeof(inet)); if (ip_family(ip) == PGSQL_AF_INET) maxbytes = 4; else maxbytes = 16; bits = ip_maxbits(ip) - ip_bits(ip); b = ip_addr(dst); byte = maxbytes - 1; while (bits) { if (bits >= 8) { mask = 0xff; bits -= 8; } else { mask = 0xff >> (8 - bits); bits = 0; } b[byte] = mask; byte--; } ip_family(dst) = ip_family(ip); ip_bits(dst) = ip_maxbits(ip); SET_INET_VARSIZE(dst); PG_RETURN_INET_P(dst);}/* * Convert a value of a network datatype to an approximate scalar value. * This is used for estimating selectivities of inequality operators * involving network types. */doubleconvert_network_to_scalar(Datum value, Oid typid){ switch (typid) { case INETOID: case CIDROID: { inet *ip = DatumGetInetP(value); int len; double res; int i; /* * Note that we don't use the full address for IPv6. */ if (ip_family(ip) == PGSQL_AF_INET) len = 4; else len = 5; res = ip_family(ip); for (i = 0; i < len; i++) { res *= 256; res += ip_addr(ip)[i]; } return res; break; } case MACADDROID: { macaddr *mac = DatumGetMacaddrP(value); double res; res = (mac->a << 16) | (mac->b << 8) | (mac->c); res *= 256 * 256 * 256; res += (mac->d << 16) | (mac->e << 8) | (mac->f); return res; } } /* * Can't get here unless someone tries to use scalarltsel/scalargtsel on * an operator with one network and one non-network operand. */ elog(ERROR, "unsupported type: %u", typid); return 0;}/* * int * bitncmp(l, r, n) * compare bit masks l and r, for n bits. * return: * -1, 1, or 0 in the libc tradition. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0x11110000 in its fourth octet. * author: * Paul Vixie (ISC), June 1996 */static intbitncmp(void *l, void *r, int n){ u_int lb, rb; int x, b;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -