コード例 #1
0
ファイル: comms.c プロジェクト: nabnut/zabbix2.0-cookies
char	*get_ip_by_socket(zbx_sock_t *s)
{
	ZBX_SOCKADDR	sa;
	ZBX_SOCKLEN_T	sz;
	static char	buffer[64];

	*buffer = '\0';

	sz = sizeof(sa);
	if (ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr*)&sa, &sz))
	{
		zbx_set_tcp_strerror("connection rejected, getpeername() failed: %s",
				strerror_from_system(zbx_sock_last_error()));
		return buffer;
	}

#if defined(HAVE_IPV6)
	if (0 != getnameinfo((struct sockaddr*)&sa, sizeof(sa), buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST))
	{
		zbx_set_tcp_strerror("connection rejected, getnameinfo() failed: %s",
				strerror_from_system(zbx_sock_last_error()));
	}
#else
	zbx_snprintf(buffer, sizeof(buffer), "%s", inet_ntoa(sa.sin_addr));
#endif

	return buffer;
}
コード例 #2
0
ファイル: jatcp.c プロジェクト: mastering-jaz/jobarranger
/******************************************************************************
 *                                                                            *
 * Function:                                                                  *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int ja_tcp_accept(zbx_sock_t * s)
{
    ZBX_SOCKADDR serv_addr;
    ZBX_SOCKLEN_T nlen;
    const char *__function_name = "ja_tcp_accept";

    zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

    zbx_tcp_unaccept(s);
    nlen = sizeof(serv_addr);

    if (ZBX_SOCK_ERROR ==
        (s->socket =
         (ZBX_SOCKET) accept(s->sockets[0], (struct sockaddr *) &serv_addr,
                             &nlen))) {
        if (zbx_sock_last_error() == EINTR)
            return SUCCEED;
        zabbix_log(LOG_LEVEL_WARNING, "accept() failed: %s %d",
                   strerror_from_system(zbx_sock_last_error()),
                   zbx_sock_last_error());

        return FAIL;
    }

    s->socket_orig = ZBX_SOCK_ERROR;
    s->accepted = 1;

    return SUCCEED;
}
コード例 #3
0
ファイル: comms.c プロジェクト: rennhak/zabbix
char	*get_ip_by_socket(zbx_sock_t *s)
{
#if defined(HAVE_IPV6)
	struct		sockaddr_storage sa;
#else
	ZBX_SOCKADDR	sa;
#endif
	socklen_t	sz;
	static char	buffer[64];

	zabbix_log( LOG_LEVEL_DEBUG, "In get_ip_by_socket()");

	*buffer = '\0';

	sz = sizeof(sa);
	if (ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr*)&sa, &sz))
	{
		zbx_set_tcp_strerror("Connection rejected. getpeername failed [%s]",
				strerror_from_system(zbx_sock_last_error()));
		return buffer;
	}

#if defined(HAVE_IPV6)
	if (0 != getnameinfo((struct sockaddr*)&sa, sizeof(sa), buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST))
	{
		zbx_set_tcp_strerror("Connection rejected. getnameinfo failed [%s] ",
				strerror_from_system(zbx_sock_last_error()));
	}
#else
	zbx_snprintf(buffer, sizeof(buffer), "%s", inet_ntoa(sa.sin_addr));
#endif

	return buffer;
}
コード例 #4
0
ファイル: telnet.c プロジェクト: 0000-bigtree/zabbix
static int	telnet_waitsocket(ZBX_SOCKET socket_fd, int mode)
{
	const char	*__function_name = "telnet_waitsocket";
	struct timeval	tv;
	int		rc;
	fd_set		fd, *readfd = NULL, *writefd = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	tv.tv_sec = 0;
	tv.tv_usec = 100000;	/* 1/10 sec */

	FD_ZERO(&fd);
	FD_SET(socket_fd, &fd);

	if (WAIT_READ == mode)
		readfd = &fd;
	else
		writefd = &fd;

	rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &tv);

	if (ZBX_TCP_ERROR == rc)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s() rc:%d errno:%d error:[%s]", __function_name, rc,
				zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, rc);

	return rc;
}
コード例 #5
0
ファイル: comms.c プロジェクト: abhilash07/agent
char	*get_ip_by_socket(zbx_sock_t *s)
{
	ZBX_SOCKADDR	sa;
	ZBX_SOCKLEN_T	sz = sizeof(sa);
	static char	host[64];
	char		*error_message = NULL;

	if (ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr*)&sa, &sz))
	{
		error_message = strerror_from_system(zbx_sock_last_error());
		zbx_set_tcp_strerror("connection rejected, getpeername() failed: %s", error_message);
		goto out;
	}

#if defined(HAVE_IPV6)
	if (0 != zbx_getnameinfo((struct sockaddr *)&sa, host, sizeof(host), NULL, 0, NI_NUMERICHOST))
	{
		error_message = strerror_from_system(zbx_sock_last_error());
		zbx_set_tcp_strerror("connection rejected, getnameinfo() failed: %s", error_message);
	}
#else
	zbx_snprintf(host, sizeof(host), "%s", inet_ntoa(sa.sin_addr));
#endif

out:
	if (NULL != error_message)
	{
		zabbix_log(LOG_LEVEL_WARNING, "Cannot get socket IP address: %s", error_message);
		strscpy(host, "unknown IP");
	}

	return host;
}
コード例 #6
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int	zbx_tcp_accept(zbx_sock_t *s)
{
	struct sockaddr_storage	serv_addr;
	fd_set			sock_set;
	ZBX_SOCKET		accepted_socket;
	socklen_t		nlen;
	int			i, n = 0;

	zbx_tcp_unaccept(s);

	FD_ZERO(&sock_set);

	/* For connection orientated protocols, we will handle the
	   packets comprising a connection collectively.  For datagram
	   protocols, we have to handle each datagram individually.

	   Check to see if we have any sockets remaining to be served
	   from previous time through this loop.  If not, call select()
	   to wait for a connection request or a datagram to arrive. */

	for(i = 0; i < s->num_socks; i++) {
#if !defined(_WINDOWS)
		if(s->sockets[i] > n)
			n = s->sockets[i];
#endif
		if(FD_ISSET(s->sockets[i], &sock_set))
			break;
	}

	if(i == s->num_socks) {
		for (i = 0; i < s->num_socks; i++)
			FD_SET(s->sockets[i], &sock_set);
		if(select(n + 1, &sock_set, 0, 0, 0) == ZBX_TCP_ERROR) {
			zbx_set_tcp_strerror("select() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
			return	FAIL;
		}
	}
	for (i = 0; i < s->num_socks; i++) {
		if (FD_ISSET(s->sockets[i], &sock_set)) {
			FD_CLR(s->sockets[i], &sock_set);
			break;
		}
	}

	/* Since this socket was returned by the select(), we know we
	   have a connection waiting and that this accept() won't block.*/
	nlen = sizeof(serv_addr);
	if((accepted_socket = (ZBX_SOCKET)accept(s->sockets[i], (struct sockaddr *)&serv_addr, &nlen)) == ZBX_SOCK_ERROR) {
		zbx_set_tcp_strerror("accept() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}

	s->socket2	= s->socket;		/* remember main socket */
	s->socket	= accepted_socket;	/* replace socket to accepted */
	s->accepted	= 1;

	return SUCCEED;
}
コード例 #7
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int zbx_tcp_listen(
	zbx_sock_t	*s,
	const char	*listen_ip,
	unsigned short	listen_port
	)
{
	ZBX_SOCKADDR	serv_addr;
	int		on, res = FAIL;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	if(ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)))
	{
		zbx_set_tcp_strerror("Cannot create socket [%s:%u] [%s]", listen_ip, listen_port, strerror_from_system(zbx_sock_last_error()));
		goto out;
	}

	/* Enable address reuse */
	/* This is to immediately use the address even if it is in TIME_WAIT state */
	/* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */
	on = 1;
	if( -1 == setsockopt(s->socket, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on) ))
	{
		zbx_set_tcp_strerror("Cannot setsockopt SO_REUSEADDR [%s]", strerror_from_system(zbx_sock_last_error()));
	}

	/* Create socket	Fill in local address structure */
	memset(&serv_addr, 0, sizeof(ZBX_SOCKADDR));

	serv_addr.sin_family		= AF_INET;
	serv_addr.sin_addr.s_addr	= listen_ip ? inet_addr(listen_ip) : htonl(INADDR_ANY);
	serv_addr.sin_port		= htons((unsigned short)listen_port);

	/* Bind socket */
	if (ZBX_SOCK_ERROR == bind(s->socket,(struct sockaddr *)&serv_addr,sizeof(ZBX_SOCKADDR)) )
	{
		zbx_set_tcp_strerror("Cannot bind to port %u for server %s. Error [%s]. Another zabbix_agentd already running ?",
				listen_port,
				listen_ip ? listen_ip : "[ANY]",
				strerror_from_system(zbx_sock_last_error()));

		goto out;
	}

	if( ZBX_SOCK_ERROR == listen(s->socket, SOMAXCONN) )
	{
		zbx_set_tcp_strerror("Listen failed. [%s]", strerror_from_system(zbx_sock_last_error()));
		goto out;
	}
	res = SUCCEED;
out:
	return res;
}
コード例 #8
0
ファイル: comms.c プロジェクト: satterly/zabbix-stats
int	zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout)
{
	ZBX_SOCKADDR	servaddr_in, source_addr;
	struct hostent	*hp;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	if (NULL == (hp = zbx_gethost(ip)))
		return FAIL;

	servaddr_in.sin_family		= AF_INET;
	servaddr_in.sin_addr.s_addr	= ((struct in_addr *)(hp->h_addr))->s_addr;
	servaddr_in.sin_port		= htons(port);

	if (ZBX_SOCK_ERROR == (s->socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)))
	{
		zbx_set_tcp_strerror("Cannot create socket [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}

#if !defined(_WINDOWS) && defined(HAVE_FCNTL_H) && !SOCK_CLOEXEC
	fcntl(s->socket, F_SETFD, FD_CLOEXEC);
#endif

	if (NULL != source_ip)
	{
		source_addr.sin_family		= AF_INET;
		source_addr.sin_addr.s_addr	= inet_addr(source_ip);
		source_addr.sin_port		= 0;

		if (ZBX_TCP_ERROR == bind(s->socket, (struct sockaddr *)&source_addr, sizeof(ZBX_SOCKADDR)))
		{
			zbx_set_tcp_strerror("bind() failed with error %d: %s\n",
					zbx_sock_last_error(),
					strerror_from_system(zbx_sock_last_error()));
			return FAIL;
		}
	}

	if (0 != timeout)
		zbx_tcp_timeout_set(s, timeout);

	if (ZBX_TCP_ERROR == connect(s->socket, (struct sockaddr *)&servaddr_in, sizeof(ZBX_SOCKADDR)))
	{
		zbx_set_tcp_strerror("Cannot connect to [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error()));
		zbx_tcp_close(s);
		return FAIL;
	}

	return SUCCEED;
}
コード例 #9
0
ファイル: comms.c プロジェクト: satterly/zabbix-stats
int	zbx_tcp_send_ext(zbx_sock_t *s, const char *data, unsigned char flags, int timeout)
{
	zbx_uint64_t	len64;

	ssize_t		i = 0, written = 0;
	int		ret = SUCCEED;

	ZBX_TCP_START();

	if (0 != timeout)
		zbx_tcp_timeout_set(s, timeout);

	if( flags & ZBX_TCP_NEW_PROTOCOL )
	{
		/* Write header */
		if( ZBX_TCP_ERROR == ZBX_TCP_WRITE(s->socket, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN))
		{
			zbx_set_tcp_strerror("ZBX_TCP_WRITE() failed [%s]", strerror_from_system(zbx_sock_last_error()));
			ret = FAIL;
			goto cleanup;
		}

		len64 = (zbx_uint64_t)strlen(data);
		len64 = zbx_htole_uint64(len64);

		/* Write data length */
		if( ZBX_TCP_ERROR == ZBX_TCP_WRITE(s->socket, (char *) &len64, sizeof(len64)) )
		{
			zbx_set_tcp_strerror("ZBX_TCP_WRITE() failed [%s]", strerror_from_system(zbx_sock_last_error()));
			ret = FAIL;
			goto cleanup;
		}
	}

	while(written < (ssize_t)strlen(data))
	{
		if( ZBX_TCP_ERROR == (i = ZBX_TCP_WRITE(s->socket, data+written,(int)(strlen(data)-written))) )
		{
			zbx_set_tcp_strerror("ZBX_TCP_WRITE() failed [%s]", strerror_from_system(zbx_sock_last_error()));
			ret = FAIL;
			goto cleanup;
		}
		written += i;
	}
cleanup:
	if (0 != timeout)
		zbx_tcp_timeout_cleanup(s);

	return ret;
}
コード例 #10
0
ファイル: comms.c プロジェクト: abhilash07/agent
/******************************************************************************
 *                                                                            *
 * Function: zbx_tcp_timeout_set                                              *
 *                                                                            *
 * Purpose: set timeout for socket operations                                 *
 *                                                                            *
 * Parameters: s       - [IN] socket descriptor                               *
 *             timeout - [IN] timeout, in seconds                             *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static void	zbx_tcp_timeout_set(zbx_sock_t *s, int timeout)
{
	s->timeout = timeout;
#if defined(_WINDOWS)
	timeout *= 1000;

	if (ZBX_TCP_ERROR == setsockopt(s->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)))
		zbx_set_tcp_strerror("setsockopt() failed: %s", strerror_from_system(zbx_sock_last_error()));

	if (ZBX_TCP_ERROR == setsockopt(s->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)))
		zbx_set_tcp_strerror("setsockopt() failed: %s", strerror_from_system(zbx_sock_last_error()));
#else
	alarm(timeout);
#endif
}
コード例 #11
0
ファイル: comms.c プロジェクト: abhilash07/agent
/******************************************************************************
 *                                                                            *
 * Function: zbx_tcp_accept                                                   *
 *                                                                            *
 * Purpose: permits an incoming connection attempt on a socket                *
 *                                                                            *
 * Return value: SUCCEED - success                                            *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Eugene Grigorjev, Aleksandrs Saveljevs                             *
 *                                                                            *
 ******************************************************************************/
int	zbx_tcp_accept(zbx_sock_t *s)
{
	ZBX_SOCKADDR	serv_addr;
	fd_set		sock_set;
	ZBX_SOCKET	accepted_socket;
	ZBX_SOCKLEN_T	nlen;
	int		i, n = 0;

	zbx_tcp_unaccept(s);

	FD_ZERO(&sock_set);

	for (i = 0; i < s->num_socks; i++)
	{
		FD_SET(s->sockets[i], &sock_set);
#if !defined(_WINDOWS)
		if (s->sockets[i] > n)
			n = s->sockets[i];
#endif
	}

	if (ZBX_TCP_ERROR == select(n + 1, &sock_set, NULL, NULL, NULL))
	{
		zbx_set_tcp_strerror("select() failed: %s", strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}

	for (i = 0; i < s->num_socks; i++)
	{
		if (FD_ISSET(s->sockets[i], &sock_set))
			break;
	}

	/* Since this socket was returned by select(), we know we have */
	/* a connection waiting and that this accept() will not block. */
	nlen = sizeof(serv_addr);
	if (ZBX_SOCK_ERROR == (accepted_socket = (ZBX_SOCKET)accept(s->sockets[i], (struct sockaddr *)&serv_addr, &nlen)))
	{
		zbx_set_tcp_strerror("accept() failed: %s", strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}

	s->socket_orig	= s->socket;		/* remember main socket */
	s->socket	= accepted_socket;	/* replace socket to accepted */
	s->accepted	= 1;

	return SUCCEED;
}
コード例 #12
0
ファイル: comms.c プロジェクト: nabnut/zabbix2.0-cookies
int	zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout)
{
	ZBX_SOCKADDR	servaddr_in, source_addr;
	struct hostent	*hp;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	if (NULL == (hp = gethostbyname(ip)))
	{
#if defined(_WINDOWS)
		zbx_set_tcp_strerror("gethostbyname() failed for '%s': %s", ip, strerror_from_system(WSAGetLastError()));
#elif defined(HAVE_HSTRERROR)
		zbx_set_tcp_strerror("gethostbyname() failed for '%s': [%d] %s", ip, h_errno, hstrerror(h_errno));
#else
		zbx_set_tcp_strerror("gethostbyname() failed for '%s': [%d]", ip, h_errno);
#endif
		return FAIL;
	}

	servaddr_in.sin_family		= AF_INET;
	servaddr_in.sin_addr.s_addr	= ((struct in_addr *)(hp->h_addr))->s_addr;
	servaddr_in.sin_port		= htons(port);

	if (ZBX_SOCK_ERROR == (s->socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)))
	{
		zbx_set_tcp_strerror("cannot create socket [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}

#if !defined(_WINDOWS) && !SOCK_CLOEXEC
	fcntl(s->socket, F_SETFD, FD_CLOEXEC);
#endif

	if (NULL != source_ip)
	{
		source_addr.sin_family		= AF_INET;
		source_addr.sin_addr.s_addr	= inet_addr(source_ip);
		source_addr.sin_port		= 0;

		if (ZBX_TCP_ERROR == bind(s->socket, (struct sockaddr *)&source_addr, sizeof(source_addr)))
		{
			zbx_set_tcp_strerror("bind() failed: %s", strerror_from_system(zbx_sock_last_error()));
			return FAIL;
		}
	}

	if (0 != timeout)
		zbx_tcp_timeout_set(s, timeout);

	if (ZBX_TCP_ERROR == connect(s->socket, (struct sockaddr *)&servaddr_in, sizeof(servaddr_in)))
	{
		zbx_set_tcp_strerror("cannot connect to [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error()));
		zbx_tcp_close(s);
		return FAIL;
	}

	return SUCCEED;
}
コード例 #13
0
ファイル: telnet.c プロジェクト: 0000-bigtree/zabbix
static ssize_t	telnet_socket_write(ZBX_SOCKET socket_fd, const void *buf, size_t count)
{
	const char	*__function_name = "telnet_socket_write";
	ssize_t		rc;
	int		error;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	while (ZBX_TCP_ERROR == (rc = ZBX_TCP_WRITE(socket_fd, buf, count)))
	{
		error = zbx_sock_last_error();	/* zabbix_log() resets the error code */
		zabbix_log(LOG_LEVEL_DEBUG, "%s() rc:%d errno:%d error:[%s]",
				__function_name, rc, error, strerror_from_system(error));

#ifdef _WINDOWS
		if (WSAEWOULDBLOCK == error)
#else
		if (EAGAIN == error)
#endif
		{
			telnet_waitsocket(socket_fd, WAIT_WRITE);
			continue;
		}

		break;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, rc);

	return rc;
}
コード例 #14
0
ファイル: comms.c プロジェクト: Shmuma/z
int	zbx_tcp_error(void)
{
	if( ZBX_SOCK_ERR_TIMEDOUT == zbx_sock_last_error() )
	{
		return ZBX_TCP_ERR_TIMEOUT;
	}

	return ZBX_TCP_ERR_NETWORK;
}
コード例 #15
0
ファイル: listener.c プロジェクト: HupuInc/zabbix
ZBX_THREAD_ENTRY(listener_thread, args)
{
	int		ret, local_request_failed = 0;
	zbx_sock_t	s;

	assert(args);
	assert(((zbx_thread_args_t *)args)->args);

	process_type = ((zbx_thread_args_t *)args)->process_type;
	server_num = ((zbx_thread_args_t *)args)->server_num;
	process_num = ((zbx_thread_args_t *)args)->process_num;

	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type),
			server_num, get_process_type_string(process_type), process_num);

	memcpy(&s, (zbx_sock_t *)((zbx_thread_args_t *)args)->args, sizeof(zbx_sock_t));

	zbx_free(args);

	while (ZBX_IS_RUNNING())
	{
		zbx_setproctitle("listener #%d [waiting for connection]", process_num);

		if (SUCCEED == (ret = zbx_tcp_accept(&s)))
		{
			local_request_failed = 0;     /* reset consecutive errors counter */

			zbx_setproctitle("listener #%d [processing request]", process_num);

			if (SUCCEED == (ret = zbx_tcp_check_security(&s, CONFIG_HOSTS_ALLOWED, 0)))
				process_listener(&s);

			zbx_tcp_unaccept(&s);
		}

		if (SUCCEED == ret || EINTR == zbx_sock_last_error())
			continue;

		zabbix_log(LOG_LEVEL_DEBUG, "failed to accept an incoming connection: %s", zbx_tcp_strerror());

		if (local_request_failed++ > 1000)
		{
			zabbix_log(LOG_LEVEL_WARNING, "too many failures to accept an incoming connection");
			local_request_failed = 0;
		}

		if (ZBX_IS_RUNNING())
			zbx_sleep(1);
	}

#ifdef _WINDOWS
	ZBX_DO_EXIT();

	zbx_thread_exit(EXIT_SUCCESS);
#endif
}
コード例 #16
0
ファイル: telnet.c プロジェクト: 0000-bigtree/zabbix
static ssize_t	telnet_socket_read(ZBX_SOCKET socket_fd, void *buf, size_t count)
{
	const char	*__function_name = "telnet_socket_read";
	ssize_t		rc;
	int		error;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	while (ZBX_TCP_ERROR == (rc = ZBX_TCP_READ(socket_fd, buf, count)))
	{
		error = zbx_sock_last_error();	/* zabbix_log() resets the error code */
		zabbix_log(LOG_LEVEL_DEBUG, "%s() rc:%d errno:%d error:[%s]",
				__function_name, rc, error, strerror_from_system(error));

#ifdef _WINDOWS
		if (WSAEWOULDBLOCK == error)
#else
		if (EAGAIN == error)
#endif
		{
			/* wait and if there is still an error or no input available */
			/* we assume the other side has nothing more to say */
			if (1 > (rc = telnet_waitsocket(socket_fd, WAIT_READ)))
				goto ret;

			continue;
		}

		break;
	}

	/* when ZBX_TCP_READ returns 0, it means EOF - let's consider it a permanent error */
	/* note that if telnet_waitsocket() is zero, it is not a permanent condition */
	if (0 == rc)
		rc = ZBX_TCP_ERROR;
ret:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, rc);

	return rc;
}
コード例 #17
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int	zbx_tcp_accept(zbx_sock_t *s)
{
	ZBX_SOCKADDR	serv_addr;
	ZBX_SOCKET	accepted_socket;
	socklen_t	nlen;

	nlen = sizeof(serv_addr);

	zbx_tcp_unaccept(s);

	if(ZBX_TCP_ERROR == (accepted_socket = (ZBX_SOCKET)accept(s->socket, (struct sockaddr *)&serv_addr, &nlen)))
	{
		zbx_set_tcp_strerror("accept() failed [%s]", strerror_from_system(zbx_sock_last_error()));
		return	FAIL;
	}

	s->socket2	= s->socket;		/* remember main socket */
	s->socket	= accepted_socket;	/* replace socket to accepted */
	s->accepted	= 1;

	return	SUCCEED;
}
コード例 #18
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int	zbx_tcp_check_security(
	zbx_sock_t *s, 
	const char *ip_list, 
	int allow_if_empty
	)
{
#if defined(HAVE_IPV6)
	struct		sockaddr_storage name;
	struct		addrinfo hints, *ai = NULL;
#else
	ZBX_SOCKADDR	name;
	struct		hostent *hp;
	char		*sip;
	int		i[4], j[4];
#endif
	socklen_t	nlen;

	char	tmp[MAX_STRING_LEN], 
		sname[MAX_STRING_LEN],
		*start = NULL,
		*end = NULL,
		c = '\0';

	zabbix_log( LOG_LEVEL_DEBUG, "In check_security()");

	if( (1 == allow_if_empty) && ( !ip_list || !*ip_list ) )
	{
		return SUCCEED;
	}
	nlen = sizeof(name);
	if( ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr*)&name, &nlen))
	{
		zbx_set_tcp_strerror("Connection rejected. Getpeername failed [%s]", strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}
	else
	{
#if !defined(HAVE_IPV6)
		zbx_strlcpy(sname, inet_ntoa(name.sin_addr), sizeof(sname));

		if(sscanf(sname, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]) != 4)
		{
			return FAIL;
		}
#endif /*HAVE_IPV6*/
		strscpy(tmp,ip_list);

		for(start = tmp; start[0] != '\0';)
		{
			end = strchr(start, ',');

			if(end != NULL)
			{
				c = end[0];
				end[0] = '\0';
			}

			/* Allow IP addresses or DNS names for authorization */
#if defined(HAVE_IPV6)
			memset(&hints, 0, sizeof(hints));
			hints.ai_family = PF_UNSPEC;
			if(0 == getaddrinfo(start, NULL, &hints, &ai))
			{
				if(ai->ai_family == name.ss_family)
				{
					switch(ai->ai_family)
					{
						case AF_INET  :
							if(((struct sockaddr_in*)&name)->sin_addr.s_addr == ((struct sockaddr_in*)ai->ai_addr)->sin_addr.s_addr)
							{
								freeaddrinfo(ai);
								return SUCCEED;
							}
						case AF_INET6 :
							if(0 == memcmp(((struct sockaddr_in6*)&name)->sin6_addr.s6_addr,
									((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr,
									sizeof(struct in6_addr)))
							{
								freeaddrinfo(ai);
								return SUCCEED;
							}
					}
				}
				freeaddrinfo(ai);
			}
#else
			if( 0 != (hp = zbx_gethost(start)))
			{
				sip = inet_ntoa(*((struct in_addr *)hp->h_addr));
				if(sscanf(sip, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) == 4)
				{
					if(i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] == j[3])
					{
						return SUCCEED;
					}
				}
			}
#endif /*HAVE_IPV6*/
			if(end != NULL)
			{
				end[0] = c;
				start = end + 1;
			}
			else
			{
				break;
			}
		}

		if(end != NULL)
		{
			end[0] = c;
		}
	}
#if defined(HAVE_IPV6)
	if(0 == getnameinfo((struct sockaddr*)&name, sizeof(name), sname, sizeof(sname), NULL, 0, NI_NUMERICHOST))
	{
		zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list);
	}
	else
	{
		zbx_set_tcp_strerror("Connection rejected. Allowed server is [%s] ", ip_list);
	}
#else
	zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list);
#endif /*HAVE_IPV6*/
	return	FAIL;
}
コード例 #19
0
ファイル: comms.c プロジェクト: abhilash07/agent
/******************************************************************************
 *                                                                            *
 * Function: zbx_tcp_recv_ext                                                 *
 *                                                                            *
 * Purpose: receive data                                                      *
 *                                                                            *
 * Return value: number of bytes received - success,                          *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 ******************************************************************************/
ssize_t	zbx_tcp_recv_ext(zbx_sock_t *s, char **data, unsigned char flags, int timeout)
{
#define ZBX_BUF_LEN	(ZBX_STAT_BUF_LEN * 8)
	ssize_t		nbytes, left, total_bytes;
	size_t		allocated, offset, read_bytes;
	zbx_uint64_t	expected_len;

	ZBX_TCP_START();

	if (0 != timeout)
		zbx_tcp_timeout_set(s, timeout);

	zbx_free(s->buf_dyn);

	total_bytes = 0;
	read_bytes = 0;
	s->buf_type = ZBX_BUF_TYPE_STAT;

	*data = s->buf_stat;

	left = ZBX_TCP_HEADER_LEN;

	if (ZBX_TCP_ERROR == (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, left)))
		goto out;

	if (ZBX_TCP_HEADER_LEN == nbytes && 0 == strncmp(s->buf_stat, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN))
	{
		total_bytes += nbytes;

		left = sizeof(zbx_uint64_t);
		if (left != (nbytes = ZBX_TCP_READ(s->socket, (void *)&expected_len, left)))
		{
			total_bytes = FAIL;
			goto out;
		}

		expected_len = zbx_letoh_uint64(expected_len);

		if (ZBX_MAX_RECV_DATA_SIZE < expected_len)
		{
			zabbix_log(LOG_LEVEL_WARNING, "Message size " ZBX_FS_UI64 " from %s"
					" exceeds the maximum size " ZBX_FS_UI64 " bytes. Message ignored.",
					expected_len, get_ip_by_socket(s), (zbx_uint64_t)ZBX_MAX_RECV_DATA_SIZE);
			total_bytes = FAIL;
			goto cleanup;
		}

		flags |= ZBX_TCP_READ_UNTIL_CLOSE;
	}
	else
	{
		read_bytes = nbytes;
		expected_len = 16 * ZBX_MEBIBYTE;
	}

	s->buf_stat[read_bytes] = '\0';

	if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE))
	{
		if (0 == nbytes)
			goto cleanup;
	}
	else
	{
		if (nbytes < left)
			goto cleanup;
	}

	left = sizeof(s->buf_stat) - read_bytes - 1;

	/* check for an empty socket if exactly ZBX_TCP_HEADER_LEN bytes (without a header) were sent */
	if (0 == read_bytes || '\n' != s->buf_stat[read_bytes - 1])	/* requests to passive agents end with '\n' */
	{
		/* fill static buffer */
		while (read_bytes < expected_len && 0 < left &&
				ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat + read_bytes, left)))
		{
			read_bytes += nbytes;

			if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE))
			{
				if (0 == nbytes)
					break;
			}
			else
			{
				if (nbytes < left)	/* should we stop reading? */
				{
					/* XML protocol? */
					if (0 == strncmp(s->buf_stat, "<req>", sizeof("<req>") - 1))
					{
						/* closing tag received in the last 10 bytes? */
						s->buf_stat[read_bytes] = '\0';
						if (NULL != strstr(s->buf_stat + read_bytes -
								(10 > read_bytes ? read_bytes : 10), "</req>"))
							break;
					}
					else
						break;
				}
			}

			left -= nbytes;
		}
	}

	s->buf_stat[read_bytes] = '\0';

	if (sizeof(s->buf_stat) - 1 == read_bytes)	/* static buffer is full */
	{
		allocated = ZBX_BUF_LEN;
		s->buf_type = ZBX_BUF_TYPE_DYN;
		s->buf_dyn = zbx_malloc(s->buf_dyn, allocated);

		memcpy(s->buf_dyn, s->buf_stat, sizeof(s->buf_stat));

		offset = read_bytes;

		/* fill dynamic buffer */
		while (read_bytes < expected_len &&
				ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, sizeof(s->buf_stat))))
		{
			zbx_strncpy_alloc(&s->buf_dyn, &allocated, &offset, s->buf_stat, nbytes);
			read_bytes += nbytes;

			if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE))
			{
				if (0 == nbytes)
					break;
			}
			else
			{
				if ((size_t)nbytes < sizeof(s->buf_stat) - 1)	/* should we stop reading? */
				{
					/* XML protocol? */
					if (0 == strncmp(s->buf_dyn, "<req>", sizeof("<req>") - 1))
					{
						/* closing tag received in the last 10 bytes? */
						if (NULL != strstr(s->buf_dyn + read_bytes - 10, "</req>"))
							break;
					}
					else
						break;
				}
			}
		}

		*data = s->buf_dyn;
	}
out:
	if (ZBX_TCP_ERROR == nbytes)
	{
		zbx_set_tcp_strerror("ZBX_TCP_READ() failed: %s", strerror_from_system(zbx_sock_last_error()));
		total_bytes = FAIL;
	}
cleanup:
	if (0 != timeout)
		zbx_tcp_timeout_cleanup(s);

	if (FAIL != total_bytes)
		total_bytes += read_bytes;

	return total_bytes;
}
コード例 #20
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int zbx_tcp_listen(
	zbx_sock_t	*s,
	const char	*listen_ip,
	unsigned short	listen_port
	)
{
	struct		addrinfo hints, *ai = NULL, *current_ai;
	char		port[MAX_STRING_LEN];
	int		e, on, ret = FAIL;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;
	zbx_snprintf(port, sizeof(port), "%d", listen_port);
	if(0 != (e = getaddrinfo(listen_ip, port, &hints, &ai)))
	{
		zbx_set_tcp_strerror("Cannot resolve address [[%s]:%u], error %d: %s", listen_ip, listen_port, e, gai_strerror(e));
		goto out;
	}

	for(s->num_socks = 0, current_ai = ai; current_ai != NULL; current_ai = current_ai->ai_next)
	{
		if(s->num_socks == FD_SETSIZE) {
			break;
		}
		/* This example only supports PF_INET and PF_INET6. */
		if((current_ai->ai_family != PF_INET) && (current_ai->ai_family != PF_INET6))
			continue;

		if((s->sockets[s->num_socks] = socket(current_ai->ai_family, current_ai->ai_socktype, current_ai->ai_protocol)) == ZBX_SOCK_ERROR) {
			zbx_set_tcp_strerror("socket() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
			continue;
		}

		/* Enable address reuse */
		/* This is to immediately use the address even if it is in TIME_WAIT state */
		/* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */
		on = 1;
		if(setsockopt(s->sockets[s->num_socks], SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) == ZBX_TCP_ERROR)
		{
			zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
		}

		/* Create socket	Fill in local address structure */
		if(bind(s->sockets[s->num_socks], current_ai->ai_addr, current_ai->ai_addrlen) == ZBX_TCP_ERROR) {
			zbx_set_tcp_strerror("bind() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
			zbx_sock_close(s->sockets[s->num_socks]);
			continue;
		}

		if(ZBX_SOCK_ERROR == listen(s->sockets[s->num_socks], SOMAXCONN) )
		{
			zbx_set_tcp_strerror("listen() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
			zbx_sock_close(s->sockets[s->num_socks]);
			continue;
		}

		s->num_socks++;
	}

	if(s->num_socks == 0) {
		zbx_set_tcp_strerror("zbx_tcp_listen() Fatal error: unable to serve on any address. [[%s]:%u]", listen_ip, listen_port);
		goto out;
	}
	ret = SUCCEED;
out:
	if (NULL != ai)
		freeaddrinfo(ai);
	return ret;
}
コード例 #21
0
ファイル: comms.c プロジェクト: abhilash07/agent
int	zbx_tcp_listen(zbx_sock_t *s, const char *listen_ip, unsigned short listen_port)
{
	ZBX_SOCKADDR	serv_addr;
	char		*ip, *ips, *delim;
	int		i, on, ret = FAIL;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	ip = ips = (NULL == listen_ip ? NULL : strdup(listen_ip));

	while (1)
	{
		delim = (NULL == ip ? NULL : strchr(ip, ','));
		if (NULL != delim)
			*delim = '\0';

		if (NULL != ip && FAIL == is_ip4(ip))
		{
			zbx_set_tcp_strerror("incorrect IPv4 address [%s]", ip);
			goto out;
		}

		if (ZBX_SOCKET_COUNT == s->num_socks)
		{
			zbx_set_tcp_strerror("not enough space for socket [[%s]:%hu]",
					ip ? ip : "-", listen_port);
			goto out;
		}

		if (ZBX_SOCK_ERROR == (s->sockets[s->num_socks] = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)))
		{
			zbx_set_tcp_strerror("socket() for [[%s]:%hu] failed: %s",
					ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error()));
			goto out;
		}

#if !defined(_WINDOWS) && !SOCK_CLOEXEC
		fcntl(s->sockets[s->num_socks], F_SETFD, FD_CLOEXEC);
#endif

		/* Enable address reuse */
		/* This is to immediately use the address even if it is in TIME_WAIT state */
		/* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */
		on = 1;
		if (ZBX_TCP_ERROR == setsockopt(s->sockets[s->num_socks], SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)))
		{
			zbx_set_tcp_strerror("setsockopt() for [[%s]:%hu] failed: %s",
					ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error()));
		}

		memset(&serv_addr, 0, sizeof(serv_addr));

		serv_addr.sin_family		= AF_INET;
		serv_addr.sin_addr.s_addr	= NULL != ip ? inet_addr(ip) : htonl(INADDR_ANY);
		serv_addr.sin_port		= htons((unsigned short)listen_port);

		if (ZBX_TCP_ERROR == bind(s->sockets[s->num_socks], (struct sockaddr *)&serv_addr, sizeof(serv_addr)))
		{
			zbx_set_tcp_strerror("bind() for [[%s]:%hu] failed: %s",
					ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error()));
			zbx_sock_close(s->sockets[s->num_socks]);
			goto out;
		}

		if (ZBX_TCP_ERROR == listen(s->sockets[s->num_socks], SOMAXCONN))
		{
			zbx_set_tcp_strerror("listen() for [[%s]:%hu] failed: %s",
					ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error()));
			zbx_sock_close(s->sockets[s->num_socks]);
			goto out;
		}

		s->num_socks++;

		if (NULL == ip || NULL == delim)
			break;
		*delim = ',';
		ip = delim + 1;
	}

	if (0 == s->num_socks)
	{
		zbx_set_tcp_strerror("zbx_tcp_listen() fatal error: unable to serve on any address [[%s]:%hu]",
				listen_ip ? listen_ip : "-", listen_port);
		goto out;
	}

	ret = SUCCEED;
out:
	if (NULL != ips)
		zbx_free(ips);

	if (SUCCEED != ret)
	{
		for (i = 0; i < s->num_socks; i++)
			zbx_sock_close(s->sockets[i]);
	}

	return ret;
}
コード例 #22
0
ファイル: comms.c プロジェクト: abhilash07/agent
int	zbx_tcp_listen(zbx_sock_t *s, const char *listen_ip, unsigned short listen_port)
{
	struct addrinfo	hints, *ai = NULL, *current_ai;
	char		port[8], *ip, *ips, *delim;
	int		i, err, on, ret = FAIL;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;
	zbx_snprintf(port, sizeof(port), "%hu", listen_port);

	ip = ips = (NULL == listen_ip ? NULL : strdup(listen_ip));

	while (1)
	{
		delim = (NULL == ip ? NULL : strchr(ip, ','));
		if (NULL != delim)
			*delim = '\0';

		if (0 != (err = getaddrinfo(ip, port, &hints, &ai)))
		{
			zbx_set_tcp_strerror("cannot resolve address [[%s]:%s]: [%d] %s",
					ip ? ip : "-", port, err, gai_strerror(err));
			goto out;
		}

		for (current_ai = ai; NULL != current_ai; current_ai = current_ai->ai_next)
		{
			if (ZBX_SOCKET_COUNT == s->num_socks)
			{
				zbx_set_tcp_strerror("not enough space for socket [[%s]:%s]",
						ip ? ip : "-", port);
				goto out;
			}

			if (PF_INET != current_ai->ai_family && PF_INET6 != current_ai->ai_family)
				continue;

			if (ZBX_SOCK_ERROR == (s->sockets[s->num_socks] =
					socket(current_ai->ai_family, current_ai->ai_socktype | SOCK_CLOEXEC, current_ai->ai_protocol)))
			{
				zbx_set_tcp_strerror("socket() for [[%s]:%s] failed: %s",
						ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error()));
#ifdef _WINDOWS
				if (WSAEAFNOSUPPORT == zbx_sock_last_error())
#else
				if (EAFNOSUPPORT == zbx_sock_last_error())
#endif
					continue;
				else
					goto out;
			}

#if !defined(_WINDOWS) && !SOCK_CLOEXEC
			fcntl(s->sockets[s->num_socks], F_SETFD, FD_CLOEXEC);
#endif

			/* enable address reuse */
			/* this is to immediately use the address even if it is in TIME_WAIT state */
			/* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */
			on = 1;
			if (ZBX_TCP_ERROR == setsockopt(s->sockets[s->num_socks], SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)))
			{
				zbx_set_tcp_strerror("setsockopt() with SO_REUSEADDR for [[%s]:%s] failed: %s",
						ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error()));
			}

#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
			if (PF_INET6 == current_ai->ai_family &&
				ZBX_TCP_ERROR == setsockopt(s->sockets[s->num_socks], IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on)))
			{
				zbx_set_tcp_strerror("setsockopt() with IPV6_V6ONLY for [[%s]:%s] failed: %s",
						ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error()));
			}
#endif
			if (ZBX_TCP_ERROR == bind(s->sockets[s->num_socks], current_ai->ai_addr, current_ai->ai_addrlen))
			{
				zbx_set_tcp_strerror("bind() for [[%s]:%s] failed: %s",
						ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error()));
				zbx_sock_close(s->sockets[s->num_socks]);
#ifdef _WINDOWS
				if (WSAEADDRINUSE == zbx_sock_last_error())
#else
				if (EADDRINUSE == zbx_sock_last_error())
#endif
					continue;
				else
					goto out;
			}

			if (ZBX_TCP_ERROR == listen(s->sockets[s->num_socks], SOMAXCONN))
			{
				zbx_set_tcp_strerror("listen() for [[%s]:%s] failed: %s",
						ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error()));
				zbx_sock_close(s->sockets[s->num_socks]);
				goto out;
			}

			s->num_socks++;
		}

		if (NULL != ai)
		{
			freeaddrinfo(ai);
			ai = NULL;
		}

		if (NULL == ip || NULL == delim)
			break;

		*delim = ',';
		ip = delim + 1;
	}

	if (0 == s->num_socks)
	{
		zbx_set_tcp_strerror("zbx_tcp_listen() fatal error: unable to serve on any address [[%s]:%hu]",
				listen_ip ? listen_ip : "-", listen_port);
		goto out;
	}

	ret = SUCCEED;
out:
	if (NULL != ips)
		zbx_free(ips);

	if (NULL != ai)
		freeaddrinfo(ai);

	if (SUCCEED != ret)
	{
		for (i = 0; i < s->num_socks; i++)
			zbx_sock_close(s->sockets[i]);
	}

	return ret;
}
コード例 #23
0
ファイル: comms.c プロジェクト: abhilash07/agent
int	zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout)
{
	int		ret = FAIL;
	struct addrinfo	*ai = NULL, hints;
	struct addrinfo	*ai_bind = NULL;
	char		service[8];

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	zbx_snprintf(service, sizeof(service), "%d", port);
	memset(&hints, 0x00, sizeof(struct addrinfo));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if (0 != getaddrinfo(ip, service, &hints, &ai))
	{
		zbx_set_tcp_strerror("cannot resolve [%s]", ip);
		goto out;
	}

	if (ZBX_SOCK_ERROR == (s->socket = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC, ai->ai_protocol)))
	{
		zbx_set_tcp_strerror("cannot create socket [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error()));
		goto out;
	}

#if !defined(_WINDOWS) && !SOCK_CLOEXEC
	fcntl(s->socket, F_SETFD, FD_CLOEXEC);
#endif

	if (NULL != source_ip)
	{
		memset(&hints, 0x00, sizeof(struct addrinfo));

		hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_NUMERICHOST;

		if (0 != getaddrinfo(source_ip, NULL, &hints, &ai_bind))
		{
			zbx_set_tcp_strerror("invalid source IP address [%s]", source_ip);
			goto out;
		}

		if (ZBX_TCP_ERROR == bind(s->socket, ai_bind->ai_addr, ai_bind->ai_addrlen))
		{
			zbx_set_tcp_strerror("bind() failed: %s", strerror_from_system(zbx_sock_last_error()));
			goto out;
		}
	}

	if (0 != timeout)
		zbx_tcp_timeout_set(s, timeout);

	if (ZBX_TCP_ERROR == connect(s->socket, ai->ai_addr, ai->ai_addrlen))
	{
		zbx_set_tcp_strerror("cannot connect to [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error()));
		zbx_tcp_close(s);
		goto out;
	}

	ret = SUCCEED;
out:
	if (NULL != ai)
		freeaddrinfo(ai);

	if (NULL != ai_bind)
		freeaddrinfo(ai_bind);

	return ret;
}
コード例 #24
0
ファイル: comms.c プロジェクト: abhilash07/agent
/******************************************************************************
 *                                                                            *
 * Function: zbx_tcp_check_security                                           *
 *                                                                            *
 * Purpose: check if connection initiator is in list of IP addresses          *
 *                                                                            *
 * Parameters: s - socket descriptor                                          *
 *             ip_list - comma-delimited list of IP addresses                 *
 *             allow_if_empty - allow connection if no IP given               *
 *                                                                            *
 * Return value: SUCCEED - connection allowed                                 *
 *               FAIL - connection is not allowed                             *
 *                                                                            *
 * Author: Alexei Vladishev, Dmitry Borovikov                                 *
 *                                                                            *
 * Comments: standard, compatible and IPv4-mapped addresses are treated       *
 *           the same: 127.0.0.1 == ::127.0.0.1 == ::ffff:127.0.0.1           *
 *                                                                            *
 ******************************************************************************/
int	zbx_tcp_check_security(zbx_sock_t *s, const char *ip_list, int allow_if_empty)
{
#if defined(HAVE_IPV6)
	struct addrinfo	hints, *ai = NULL, *current_ai;
#else
	struct hostent	*hp;
	int		i;
#endif
	ZBX_SOCKADDR	name;
	ZBX_SOCKLEN_T	nlen;

	char		tmp[MAX_STRING_LEN], *start = NULL, *end = NULL;

	if (1 == allow_if_empty && (NULL == ip_list || '\0' == *ip_list))
		return SUCCEED;

	nlen = sizeof(name);

	if (ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr *)&name, &nlen))
	{
		zbx_set_tcp_strerror("connection rejected, getpeername() failed: %s",
				strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}
	else
	{
		strscpy(tmp, ip_list);

		for (start = tmp; '\0' != *start;)
		{
			if (NULL != (end = strchr(start, ',')))
				*end = '\0';

			/* allow IP addresses or DNS names for authorization */
#if defined(HAVE_IPV6)
			memset(&hints, 0, sizeof(hints));
			hints.ai_family = PF_UNSPEC;
			if (0 == getaddrinfo(start, NULL, &hints, &ai))
			{
				for (current_ai = ai; NULL != current_ai; current_ai = current_ai->ai_next)
				{
					if (SUCCEED == zbx_ip_cmp(current_ai, name))
					{
						freeaddrinfo(ai);
						return SUCCEED;
					}
				}
				freeaddrinfo(ai);
			}
#else
			if (NULL != (hp = gethostbyname(start)))
			{
				for (i = 0; NULL != hp->h_addr_list[i]; i++)
				{
					if (name.sin_addr.s_addr == ((struct in_addr *)hp->h_addr_list[i])->s_addr)
						return SUCCEED;
				}
			}
#endif	/* HAVE_IPV6 */
			if (NULL != end)
			{
				*end = ',';
				start = end + 1;
			}
			else
				break;
		}

		if (NULL != end)
			*end = ',';
	}
#if defined(HAVE_IPV6)
	if (0 == zbx_getnameinfo((struct sockaddr *)&name, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST))
		zbx_set_tcp_strerror("connection from \"%s\" rejected, allowed hosts: \"%s\"", tmp, ip_list);
	else
		zbx_set_tcp_strerror("connection rejected, allowed hosts: \"%s\"", ip_list);
#else
	zbx_set_tcp_strerror("connection from \"%s\" rejected, allowed hosts: \"%s\"", inet_ntoa(name.sin_addr), ip_list);
#endif
	return FAIL;
}
コード例 #25
0
ファイル: comms.c プロジェクト: satterly/zabbix-stats
/******************************************************************************
 *                                                                            *
 * Function: zbx_tcp_recv                                                     *
 *                                                                            *
 * Purpose: receive data                                                      *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCEED - success                                            *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	zbx_tcp_recv_ext(zbx_sock_t *s, char **data, unsigned char flags, int timeout)
{
#define ZBX_BUF_LEN	ZBX_STAT_BUF_LEN*8

	ssize_t		nbytes, left;
	ssize_t		read_bytes;

	int		allocated, offset;
	int		ret = SUCCEED;
	zbx_uint64_t	expected_len;

	ZBX_TCP_START();

	if (0 != timeout)
		zbx_tcp_timeout_set(s, timeout);

	zbx_free(s->buf_dyn);

	memset(s->buf_stat, 0, sizeof(s->buf_stat));
	*data = s->buf_stat;

	read_bytes = 0;
	s->buf_type = ZBX_BUF_TYPE_STAT;

	left = ZBX_TCP_HEADER_LEN;
	nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, left);

	if( ZBX_TCP_HEADER_LEN == nbytes && 0 == strncmp(s->buf_stat, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN) )
	{

		left = sizeof(zbx_uint64_t);
		nbytes = ZBX_TCP_READ(s->socket, (void *)&expected_len, left);
		expected_len = zbx_letoh_uint64(expected_len);

		/* The rest was already cleared */
		memset(s->buf_stat, 0, ZBX_TCP_HEADER_LEN);

		flags |= ZBX_TCP_READ_UNTIL_CLOSE;
	}
	else if( ZBX_TCP_ERROR != nbytes )
	{
		read_bytes	= nbytes;
		expected_len	= 16*1024*1024;
	}

	if( ZBX_TCP_ERROR != nbytes )
	{
		if( flags & ZBX_TCP_READ_UNTIL_CLOSE ) {
			if(nbytes == 0)		goto cleanup;
		} else {
			if(nbytes < left)	goto cleanup;
		}

		left = sizeof(s->buf_stat) - read_bytes - 1;

		/* fill static buffer */
		if ( s->buf_stat[ read_bytes - 1 ] != '\n' ) /* Don't try to read from an empty socket. */
		{
			while(	read_bytes < expected_len && left > 0
				&& ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ( s->socket, s->buf_stat + read_bytes, left)))
			{
				read_bytes += nbytes;

				if( flags & ZBX_TCP_READ_UNTIL_CLOSE )
				{
					if(nbytes == 0)	break;
				}
				else
				{
					if(nbytes < left) break;
				}

				left -= nbytes;
			}
		}

		s->buf_stat[read_bytes] = '\0';
		if( (sizeof(s->buf_stat) - 1) == read_bytes) /* static buffer is full */
		{
			allocated		= ZBX_BUF_LEN;

			s->buf_type		= ZBX_BUF_TYPE_DYN;
			s->buf_dyn		= zbx_malloc(s->buf_dyn, allocated);

			memset(s->buf_dyn, 0, allocated);
			memcpy(s->buf_dyn, s->buf_stat, sizeof(s->buf_stat));

			offset = read_bytes;
			/* fill dynamic buffer */
			while( read_bytes < expected_len && ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, sizeof(s->buf_stat)-1)) )
			{
				s->buf_stat[nbytes] = '\0';
				zbx_snprintf_alloc(&(s->buf_dyn), &allocated, &offset, sizeof(s->buf_stat), "%s", s->buf_stat);
				read_bytes += nbytes;

				if( flags & ZBX_TCP_READ_UNTIL_CLOSE ) {
					if(nbytes == 0)	break;
				} else {
					if(nbytes < sizeof(s->buf_stat) - 1) break;
				}
			}

			*data = s->buf_dyn;
		}
	}

	if( ZBX_TCP_ERROR == nbytes )
	{
		zbx_set_tcp_strerror("ZBX_TCP_READ() failed [%s]", strerror_from_system(zbx_sock_last_error()));
		ret = FAIL;
	}
cleanup:
	if (0 != timeout)
		zbx_tcp_timeout_cleanup(s);

	return ret;
}
コード例 #26
0
ファイル: comms.c プロジェクト: satterly/zabbix-stats
/******************************************************************************
 *                                                                            *
 * Function: zbx_gethost                                                      *
 *                                                                            *
 * Purpose: retrieve 'hostent' by host name and IP                            *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: hostent or NULL - an error occurred                          *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
struct hostent	*zbx_gethost(const char *hostname)
{
	unsigned int	addr;
	struct hostent	*host;

	assert(hostname);

	host = gethostbyname(hostname);
	if(host)	return host;

	addr = inet_addr(hostname);

	host = gethostbyaddr((char *)&addr, 4, AF_INET);

	if(host)	return host;


	zbx_set_tcp_strerror("gethost() failed for address '%s' [%s]", hostname, strerror_from_system(zbx_sock_last_error()));

	return (struct hostent *)NULL;
}
コード例 #27
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int	zbx_tcp_connect(zbx_sock_t *s,
	const char	*source_ip,
	const char	*ip,
	unsigned short	port,
	int		timeout
	)
{
	ZBX_SOCKADDR	servaddr_in, source_addr;
	struct	hostent *hp;

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	if (NULL == (hp = zbx_gethost(ip))) {
		zbx_set_tcp_strerror("Cannot resolve [%s]", ip);
		return	FAIL;
	}

	servaddr_in.sin_family		= AF_INET;
	servaddr_in.sin_addr.s_addr	= ((struct in_addr *)(hp->h_addr))->s_addr;
	servaddr_in.sin_port		= htons(port);

	if (ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0))) {
		zbx_set_tcp_strerror("Cannot create socket [%s:%d] [%s]", ip, port ,strerror_from_system(zbx_sock_last_error()));
		return	FAIL;
	}

	if (NULL != source_ip)
	{
		source_addr.sin_family		= AF_INET;
		source_addr.sin_addr.s_addr	= inet_addr(source_ip);
		source_addr.sin_port		= 0;

		if (ZBX_SOCK_ERROR == bind(s->socket, (struct sockaddr *)&source_addr, sizeof(ZBX_SOCKADDR)) )
		{
			zbx_set_tcp_strerror("bind() failed with error %d: %s\n",
					zbx_sock_last_error(),
					strerror_from_system(zbx_sock_last_error()));
			return FAIL;
		}
	}

	if (0 != timeout) {
		s->timeout = timeout;
#if defined(_WINDOWS)
		timeout *= 1000;
		if (setsockopt(s->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR)
			zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));

		if (setsockopt(s->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR)
			zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
#else
		alarm(timeout);
#endif
	}

	if (ZBX_TCP_ERROR == connect(s->socket,(struct sockaddr *)&servaddr_in,sizeof(ZBX_SOCKADDR))) {
		zbx_set_tcp_strerror("Cannot connect to [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error()));
		zbx_tcp_close(s);
		return	FAIL;
	}

	return SUCCEED;
}
コード例 #28
0
ファイル: comms.c プロジェクト: nabnut/zabbix2.0-cookies
/******************************************************************************
 *                                                                            *
 * Function: check_security                                                   *
 *                                                                            *
 * Purpose: check if connection initiator is in list of IP addresses          *
 *                                                                            *
 * Parameters: sockfd - socket descriptor                                     *
 *             ip_list - comma-delimited list of IP addresses                 *
 *             allow_if_empty - allow connection if no IP given               *
 *                                                                            *
 * Return value: SUCCEED - connection allowed                                 *
 *               FAIL - connection is not allowed                             *
 *                                                                            *
 * Author: Alexei Vladishev, Dmitry Borovikov                                 *
 *                                                                            *
 * Comments: standard, compatible and IPv4-mapped addresses are treated       *
 *           the same: 127.0.0.1 == ::127.0.0.1 == ::ffff:127.0.0.1           *
 *                                                                            *
 ******************************************************************************/
int	zbx_tcp_check_security(zbx_sock_t *s, const char *ip_list, int allow_if_empty)
{
#if defined(HAVE_IPV6)
	struct addrinfo	hints, *ai = NULL;
	/* Network Byte Order is ensured */
	unsigned char	ipv4_cmp_mask[12] = {0};				/* IPv4-Compatible, the first 96 bits are zeros */
	unsigned char	ipv4_mpd_mask[12] = {0,0,0,0,0,0,0,0,0,0,255,255};	/* IPv4-Mapped, the first 80 bits are zeros, 16 next - ones */
#else
	struct hostent	*hp;
	char		*sip;
	int		i[4], j[4];
#endif
	ZBX_SOCKADDR	name;
	ZBX_SOCKLEN_T	nlen;

	char		tmp[MAX_STRING_LEN], sname[MAX_STRING_LEN], *start = NULL, *end = NULL;

	if (1 == allow_if_empty && (NULL == ip_list || '\0' == *ip_list))
		return SUCCEED;

	nlen = sizeof(name);

	if (ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr *)&name, &nlen))
	{
		zbx_set_tcp_strerror("connection rejected, getpeername() failed: %s", strerror_from_system(zbx_sock_last_error()));
		return FAIL;
	}
	else
	{
#if !defined(HAVE_IPV6)
		zbx_strlcpy(sname, inet_ntoa(name.sin_addr), sizeof(sname));

		if (4 != sscanf(sname, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]))
			return FAIL;
#endif
		strscpy(tmp,ip_list);

		for (start = tmp; '\0' != *start;)
		{
			if (NULL != (end = strchr(start, ',')))
				*end = '\0';

			/* allow IP addresses or DNS names for authorization */
#if defined(HAVE_IPV6)
			memset(&hints, 0, sizeof(hints));
			hints.ai_family = PF_UNSPEC;
			if (0 == getaddrinfo(start, NULL, &hints, &ai))
			{
#ifdef HAVE_SOCKADDR_STORAGE_SS_FAMILY
				if (ai->ai_family == name.ss_family)
#else
				if (ai->ai_family == name.__ss_family)
#endif
				{
					switch (ai->ai_family)
					{
						case AF_INET  :
							if (((struct sockaddr_in*)&name)->sin_addr.s_addr == ((struct sockaddr_in*)ai->ai_addr)->sin_addr.s_addr)
							{
								freeaddrinfo(ai);
								return SUCCEED;
							}
							break;
						case AF_INET6 :
							if (0 == memcmp(((struct sockaddr_in6*)&name)->sin6_addr.s6_addr,
									((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr,
									sizeof(struct in6_addr)))
							{
								freeaddrinfo(ai);
								return SUCCEED;
							}
							break;
					}
				}
				else
				{
					switch (ai->ai_family)
					{
						case AF_INET  :
							/* incoming AF_INET6, must see whether it is comp or mapped */
							if((0 == memcmp(((struct sockaddr_in6*)&name)->sin6_addr.s6_addr, ipv4_cmp_mask, 12) ||
								0 == memcmp(((struct sockaddr_in6*)&name)->sin6_addr.s6_addr, ipv4_mpd_mask, 12)) &&
								0 == memcmp(&((struct sockaddr_in6*)&name)->sin6_addr.s6_addr[12],
									(unsigned char*)&((struct sockaddr_in*)ai->ai_addr)->sin_addr.s_addr, 4))
							{
								freeaddrinfo(ai);
								return SUCCEED;
							}
							break;
						case AF_INET6 :
							/* incoming AF_INET, must see whether the given is comp or mapped */
							if((0 == memcmp(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr, ipv4_cmp_mask, 12) ||
								0 == memcmp(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr, ipv4_mpd_mask, 12)) &&
								0 == memcmp(&((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr[12],
									(unsigned char*)&((struct sockaddr_in*)&name)->sin_addr.s_addr, 4))
							{
								freeaddrinfo(ai);
								return SUCCEED;
							}
							break;
					}
				}
				freeaddrinfo(ai);
			}
#else
			if (NULL != (hp = gethostbyname(start)))
			{
				sip = inet_ntoa(*((struct in_addr *)hp->h_addr));

				if (4 == sscanf(sip, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) &&
						i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] == j[3])
				{
					return SUCCEED;
				}
			}
#endif	/* HAVE_IPV6 */
			if (NULL != end)
			{
				*end = ',';
				start = end + 1;
			}
			else
				break;
		}

		if (NULL != end)
			*end = ',';
	}
#if defined(HAVE_IPV6)
	if (0 == getnameinfo((struct sockaddr *)&name, sizeof(name), sname, sizeof(sname), NULL, 0, NI_NUMERICHOST))
		zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s].", sname, ip_list);
	else
		zbx_set_tcp_strerror("Connection rejected. Allowed server is [%s].", ip_list);
#else
	zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s].", sname, ip_list);
#endif
	return	FAIL;
}
コード例 #29
0
ファイル: comms.c プロジェクト: rennhak/zabbix
int	zbx_tcp_connect(zbx_sock_t *s,
	const char	*source_ip,
	const char	*ip, 
	unsigned short	port,
	int		timeout
	)
{
	int	ret = FAIL;
	struct	addrinfo *ai = NULL, hints;
	struct	addrinfo *ai_bind = NULL;
	char	service[MAX_STRING_LEN];

	ZBX_TCP_START();

	zbx_tcp_clean(s);

	zbx_snprintf(service, sizeof(service), "%d", port);
	memset(&hints, 0x00, sizeof(struct addrinfo));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if (0 != getaddrinfo(ip, service, &hints, &ai)) {
		zbx_set_tcp_strerror("Cannot resolve [%s]", ip);
		goto out;
	}

	if (ZBX_SOCK_ERROR == (s->socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol))) {
		zbx_set_tcp_strerror("Cannot create socket [%s]:%d [%s]", ip, port ,strerror_from_system(zbx_sock_last_error()));
		goto out;
	}

	if (NULL != source_ip)
	{
		memset(&hints, 0x00, sizeof(struct addrinfo));
		hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_NUMERICHOST;

		if (0 != getaddrinfo(source_ip, NULL, &hints, &ai_bind))
		{
			zbx_set_tcp_strerror("Invalid source IP address [%s]\n",
					source_ip);
			goto out;
		}

		if (ZBX_TCP_ERROR == bind(s->socket, ai_bind->ai_addr, ai_bind->ai_addrlen))
		{
			zbx_set_tcp_strerror("bind() failed with error %d: %s\n",
					zbx_sock_last_error(),
					strerror_from_system(zbx_sock_last_error()));
			goto out;
		}
	}

	if (0 != timeout) {
		s->timeout = timeout;
#if defined(_WINDOWS)
		timeout *= 1000;
		if (setsockopt(s->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR)
			zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));

		if (setsockopt(s->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR)
			zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error()));
#else
		alarm(timeout);
#endif
	}

	if (ZBX_TCP_ERROR == connect(s->socket, ai->ai_addr, ai->ai_addrlen)) {
		zbx_set_tcp_strerror("*** Cannot connect to [%s]:%d [%s]", ip, port, strerror_from_system(zbx_sock_last_error()));
		zbx_tcp_close(s);
		goto out;
	}

	ret = SUCCEED;
out:
	if (NULL != ai)
		freeaddrinfo(ai);

	if (NULL != ai_bind)
		freeaddrinfo(ai_bind);

	return ret;
}