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

📄 network.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))		{			if (IS_HIGHBIT_SET(lb))				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();	clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);	PG_RETURN_INET_P(network_in(remote_host, false));}/* * 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();	clean_ipv6_addr(port->laddr.addr.ss_family, local_host);	PG_RETURN_INET_P(network_in(local_host, false));}/* * 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)));}Datuminetnot(PG_FUNCTION_ARGS){	inet	   *ip = PG_GETARG_INET_P(0);	inet	   *dst;	dst = (inet *) palloc0(sizeof(inet));	{		int			nb = ip_addrsize(ip);		unsigned char *pip = ip_addr(ip);		unsigned char *pdst = ip_addr(dst);		while (nb-- > 0)			pdst[nb] = ~pip[nb];	}	ip_bits(dst) = ip_bits(ip);	ip_family(dst) = ip_family(ip);	SET_INET_VARSIZE(dst);	PG_RETURN_INET_P(dst);}Datuminetand(PG_FUNCTION_ARGS){	inet	   *ip = PG_GETARG_INET_P(0);	inet	   *ip2 = PG_GETARG_INET_P(1);	inet	   *dst;	dst = (inet *) palloc0(sizeof(inet));	if (ip_family(ip) != ip_family(ip2))		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("cannot AND inet values of different sizes")));	else	{		int			nb = ip_addrsize(ip);		unsigned char *pip = ip_addr(ip);		unsigned char *pip2 = ip_addr(ip2);		unsigned char *pdst = ip_addr(dst);		while (nb-- > 0)			pdst[nb] = pip[nb] & pip2[nb];	}	ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));	ip_family(dst) = ip_family(ip);	SET_INET_VARSIZE(dst);	PG_RETURN_INET_P(dst);}Datuminetor(PG_FUNCTION_ARGS){	inet	   *ip = PG_GETARG_INET_P(0);	inet	   *ip2 = PG_GETARG_INET_P(1);	inet	   *dst;	dst = (inet *) palloc0(sizeof(inet));	if (ip_family(ip) != ip_family(ip2))		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("cannot OR inet values of different sizes")));	else	{		int			nb = ip_addrsize(ip);		unsigned char *pip = ip_addr(ip);		unsigned char *pip2 = ip_addr(ip2);		unsigned char *pdst = ip_addr(dst);		while (nb-- > 0)			pdst[nb] = pip[nb] | pip2[nb];	}	ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));	ip_family(dst) = ip_family(ip);	SET_INET_VARSIZE(dst);	PG_RETURN_INET_P(dst);}static inet *internal_inetpl(inet *ip, int64 addend){	inet	   *dst;	dst = (inet *) palloc0(sizeof(inet));	{		int			nb = ip_addrsize(ip);		unsigned char *pip = ip_addr(ip);		unsigned char *pdst = ip_addr(dst);		int			carry = 0;		while (nb-- > 0)		{			carry = pip[nb] + (int) (addend & 0xFF) + carry;			pdst[nb] = (unsigned char) (carry & 0xFF);			carry >>= 8;			/*			 * We have to be careful about right-shifting addend because			 * right-shift isn't portable for negative values, while simply			 * dividing by 256 doesn't work (the standard rounding is in the			 * wrong direction, besides which there may be machines out there			 * that round the wrong way).  So, explicitly clear the low-order			 * byte to remove any doubt about the correct result of the			 * division, and then divide rather than shift.			 */			addend &= ~((int64) 0xFF);			addend /= 0x100;		}		/*		 * At this point we should have addend and carry both zero if original		 * addend was >= 0, or addend -1 and carry 1 if original addend was <		 * 0.  Anything else means overflow.		 */		if (!((addend == 0 && carry == 0) ||			  (addend == -1 && carry == 1)))			ereport(ERROR,					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),					 errmsg("result is out of range")));	}	ip_bits(dst) = ip_bits(ip);	ip_family(dst) = ip_family(ip);	SET_INET_VARSIZE(dst);	return dst;}Datuminetpl(PG_FUNCTION_ARGS){	inet	   *ip = PG_GETARG_INET_P(0);	int64		addend = PG_GETARG_INT64(1);	PG_RETURN_INET_P(internal_inetpl(ip, addend));}Datuminetmi_int8(PG_FUNCTION_ARGS){	inet	   *ip = PG_GETARG_INET_P(0);	int64		addend = PG_GETARG_INT64(1);	PG_RETURN_INET_P(internal_inetpl(ip, -addend));}Datuminetmi(PG_FUNCTION_ARGS){	inet	   *ip = PG_GETARG_INET_P(0);	inet	   *ip2 = PG_GETARG_INET_P(1);	int64		res = 0;	if (ip_family(ip) != ip_family(ip2))		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("cannot subtract inet values of different sizes")));	else	{		/*		 * We form the difference using the traditional complement, increment,		 * and add rule, with the increment part being handled by starting the		 * carry off at 1.	If you don't think integer arithmetic is done in		 * two's complement, too bad.		 */		int			nb = ip_addrsize(ip);		int			byte = 0;		unsigned char *pip = ip_addr(ip);		unsigned char *pip2 = ip_addr(ip2);		int			carry = 1;		while (nb-- > 0)		{			int			lobyte;			carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;			lobyte = carry & 0xFF;			if (byte < sizeof(int64))			{				res |= ((int64) lobyte) << (byte * 8);			}			else			{				/*				 * Input wider than int64: check for overflow.	All bytes to				 * the left of what will fit should be 0 or 0xFF, depending on				 * sign of the now-complete result.				 */				if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))					ereport(ERROR,							(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),							 errmsg("result is out of range")));			}			carry >>= 8;			byte++;		}		/*		 * If input is narrower than int64, overflow is not possible, but we		 * have to do proper sign extension.		 */		if (carry == 0 && byte < sizeof(int64))			res |= ((int64) -1) << (byte * 8);	}	PG_RETURN_INT64(res);}/* * clean_ipv6_addr --- remove any '%zone' part from an IPv6 address string * * XXX This should go away someday! * * This is a kluge needed because we don't yet support zones in stored inet * values.	Since the result of getnameinfo() might include a zone spec, * call this to remove it anywhere we want to feed getnameinfo's output to * network_in.	Beats failing entirely. * * An alternative approach would be to let network_in ignore %-parts for * itself, but that would mean we'd silently drop zone specs in user input, * which seems not such a good idea. */voidclean_ipv6_addr(int addr_family, char *addr){#ifdef HAVE_IPV6	if (addr_family == AF_INET6)	{		char	   *pct = strchr(addr, '%');		if (pct)			*pct = '\0';	}#endif}

⌨️ 快捷键说明

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