⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
Datumnetwork_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")];	if (ip_type(ip))		dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),							 ip_bits(ip), tmp, sizeof(tmp));	else		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);	VARATT_SIZEP(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(VARHDRSZ + sizeof(inet_struct));	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);	ip_type(dst) = 0;	VARATT_SIZEP(dst) = VARHDRSZ		+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))		+ ip_addrsize(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(VARHDRSZ + sizeof(inet_struct));	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);	ip_type(dst) = 1;	VARATT_SIZEP(dst) = VARHDRSZ		+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))		+ ip_addrsize(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(VARHDRSZ + sizeof(inet_struct));	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);	ip_type(dst) = 0;	VARATT_SIZEP(dst) = VARHDRSZ		+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))		+ ip_addrsize(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(VARHDRSZ + sizeof(inet_struct));	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);	ip_type(dst) = 0;	VARATT_SIZEP(dst) = VARHDRSZ		+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))		+ ip_addrsize(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. * * Currently, inet/cidr values are simply converted to the IPv4 address; * this will need more thought when IPv6 is supported too.	MAC addresses * are converted to their numeric equivalent as well (OK since we have a * double to play in). */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 here.				 */				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;	b = n / 8;	x = memcmp(l, r, b);	if (x)		return (x);	lb = ((const u_char *) l)[b];	rb = ((const u_char *) r)[b];	for (b = n % 8; b > 0; b--)	{		if ((lb & 0x80) != (rb & 0x80))		{			if (lb & 0x80)				return (1);			return (-1);		}		lb <<= 1;		rb <<= 1;	}	return (0);}static booladdressOK(unsigned char *a, int bits, int family){	int			byte;	int			nbits;	int			maxbits;	int			maxbytes;	unsigned char mask;	if (family == PGSQL_AF_INET)	{		maxbits = 32;		maxbytes = 4;	}	else	{		maxbits = 128;		maxbytes = 16;	}	Assert(bits <= maxbits);	if (bits == maxbits)		return true;	byte = bits / 8;	nbits = bits % 8;	mask = 0xff;	if (bits != 0)		mask >>= nbits;	while (byte < maxbytes)	{		if ((a[byte] & mask) != 0)			return false;		mask = 0xff;		byte++;	}	return true;}/* * These functions are used by planner to generate indexscan limits * for clauses a << b and a <<= b *//* return the minimal value for an IP on a given network */Datumnetwork_scan_first(Datum in){	return DirectFunctionCall1(network_network, in);}/* * return "last" IP on a given network. It's the broadcast address, * however, masklen has to be set to its max btis, since * 192.168.0.255/24 is considered less than 192.168.0.255/32 * * inet_set_masklen() hacked to max out the masklength to 128 for IPv6 * and 32 for IPv4 when given '-1' as argument. */Datumnetwork_scan_last(Datum in){	return DirectFunctionCall2(inet_set_masklen,							   DirectFunctionCall1(network_broadcast, in),							   Int32GetDatum(-1));}/* * IP address that the client is connecting from (NULL if Unix socket) */Datuminet_client_addr(PG_FUNCTION_ARGS){	Port	   *port = MyProcPort;	char		remote_host[NI_MAXHOST];	int			ret;	if (port == NULL)		PG_RETURN_NULL();	switch (port->raddr.addr.ss_family)	{		case AF_INET:#ifdef HAVE_IPV6		case AF_INET6:#endif			break;		default:			PG_RETURN_NULL();	}	remote_host[0] = '\0';	ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,							 remote_host, sizeof(remote_host),							 NULL, 0,							 NI_NUMERICHOST | NI_NUMERICSERV);	if (ret)		PG_RETURN_NULL();	PG_RETURN_INET_P(network_in(remote_host, 0));}/* * port that the client is connecting from (NULL if Unix socket) */Datuminet_client_port(PG_FUNCTION_ARGS){	Port	   *port = MyProcPort;	char		remote_port[NI_MAXSERV];	int			ret;	if (port == NULL)		PG_RETURN_NULL();	switch (port->raddr.addr.ss_family)	{		case AF_INET:#ifdef HAVE_IPV6		case AF_INET6:#endif			break;		default:			PG_RETURN_NULL();	}	remote_port[0] = '\0';	ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,							 NULL, 0,							 remote_port, sizeof(remote_port),							 NI_NUMERICHOST | NI_NUMERICSERV);	if (ret)		PG_RETURN_NULL();	PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));}/* * IP address that the server accepted the connection on (NULL if Unix socket) */Datuminet_server_addr(PG_FUNCTION_ARGS){	Port	   *port = MyProcPort;	char		local_host[NI_MAXHOST];	int			ret;	if (port == NULL)		PG_RETURN_NULL();	switch (port->laddr.addr.ss_family)	{		case AF_INET:#ifdef HAVE_IPV6		case AF_INET6:#endif			break;		default:			PG_RETURN_NULL();	}	local_host[0] = '\0';	ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,							 local_host, sizeof(local_host),							 NULL, 0,							 NI_NUMERICHOST | NI_NUMERICSERV);	if (ret)		PG_RETURN_NULL();	PG_RETURN_INET_P(network_in(local_host, 0));}/* * port that the server accepted the connection on (NULL if Unix socket) */Datuminet_server_port(PG_FUNCTION_ARGS){	Port	   *port = MyProcPort;	char		local_port[NI_MAXSERV];	int			ret;	if (port == NULL)		PG_RETURN_NULL();	switch (port->laddr.addr.ss_family)	{		case AF_INET:#ifdef HAVE_IPV6		case AF_INET6:#endif			break;		default:			PG_RETURN_NULL();	}	local_port[0] = '\0';	ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,							 NULL, 0,							 local_port, sizeof(local_port),							 NI_NUMERICHOST | NI_NUMERICSERV);	if (ret)		PG_RETURN_NULL();	PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -