1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 #include "sysinfo.h"
22 
23 #include "comms.h"
24 #include "log.h"
25 #include "cfg.h"
26 
27 #include "net.h"
28 #include "zbxalgo.h"
29 
tcp_expect(const char * host,unsigned short port,int timeout,const char * request,int (* validate_func)(const char *),const char * sendtoclose,int * value_int)30 int	tcp_expect(const char *host, unsigned short port, int timeout, const char *request,
31 		int (*validate_func)(const char *), const char *sendtoclose, int *value_int)
32 {
33 	zbx_socket_t	s;
34 	const char	*buf;
35 	int		net, val = ZBX_TCP_EXPECT_OK;
36 
37 	*value_int = 0;
38 
39 	if (SUCCEED != (net = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout, ZBX_TCP_SEC_UNENCRYPTED, NULL,
40 			NULL)))
41 	{
42 		goto out;
43 	}
44 
45 	if (NULL != request)
46 		net = zbx_tcp_send_raw(&s, request);
47 
48 	if (NULL != validate_func && SUCCEED == net)
49 	{
50 		val = ZBX_TCP_EXPECT_FAIL;
51 
52 		while (NULL != (buf = zbx_tcp_recv_line(&s)))
53 		{
54 			val = validate_func(buf);
55 
56 			if (ZBX_TCP_EXPECT_OK == val)
57 				break;
58 
59 			if (ZBX_TCP_EXPECT_FAIL == val)
60 			{
61 				zabbix_log(LOG_LEVEL_DEBUG, "TCP expect content error, received [%s]", buf);
62 				break;
63 			}
64 		}
65 	}
66 
67 	if (NULL != sendtoclose && SUCCEED == net && ZBX_TCP_EXPECT_OK == val)
68 		(void)zbx_tcp_send_raw(&s, sendtoclose);
69 
70 	if (SUCCEED == net && ZBX_TCP_EXPECT_OK == val)
71 		*value_int = 1;
72 
73 	zbx_tcp_close(&s);
74 out:
75 	if (SUCCEED != net)
76 		zabbix_log(LOG_LEVEL_DEBUG, "TCP expect network error: %s", zbx_socket_strerror());
77 
78 	return SYSINFO_RET_OK;
79 }
80 
NET_TCP_PORT(AGENT_REQUEST * request,AGENT_RESULT * result)81 int	NET_TCP_PORT(AGENT_REQUEST *request, AGENT_RESULT *result)
82 {
83 	unsigned short	port;
84 	int		value_int, ret;
85 	char		*ip_str, ip[MAX_ZBX_DNSNAME_LEN + 1], *port_str;
86 
87 	if (2 < request->nparam)
88 	{
89 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
90 		return SYSINFO_RET_FAIL;
91 	}
92 
93 	ip_str = get_rparam(request, 0);
94 	port_str = get_rparam(request, 1);
95 
96 	if (NULL == ip_str || '\0' == *ip_str)
97 		strscpy(ip, "127.0.0.1");
98 	else
99 		strscpy(ip, ip_str);
100 
101 	if (NULL == port_str || SUCCEED != is_ushort(port_str, &port))
102 	{
103 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
104 		return SYSINFO_RET_FAIL;
105 	}
106 
107 	if (SYSINFO_RET_OK == (ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int)))
108 		SET_UI64_RESULT(result, value_int);
109 
110 	return ret;
111 }
112