/****************************************************************************** * * * Function: send_to_node * * * * Purpose: send configuration changes to required node * * * * Parameters: * * * * Return value: SUCCESS - processed succesfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int send_to_node(char *name, int dest_nodeid, int nodeid, char *data) { char ip[MAX_STRING_LEN]; int port; int ret = FAIL; DB_RESULT result; DB_ROW row; zbx_sock_t sock; char *answer; zabbix_log( LOG_LEVEL_WARNING, "NODE: Sending %s to node %s:%d datalen %d", name, CONFIG_MASTER_IP, CONFIG_MASTER_PORT, strlen(data)); /* zabbix_log( LOG_LEVEL_WARNING, "Data [%s]", data);*/ if( FAIL == zbx_tcp_connect(&sock, CONFIG_MASTER_IP, CONFIG_MASTER_PORT, 0, NULL)) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to connect to Node [%s:%d] error: %s", CONFIG_MASTER_IP, CONFIG_MASTER_PORT, zbx_tcp_strerror()); return FAIL; } if( FAIL == zbx_tcp_send(&sock, data)) { zabbix_log( LOG_LEVEL_WARNING, "Error while sending data to Node [%s:%d]", CONFIG_MASTER_IP, CONFIG_MASTER_PORT); zbx_tcp_close(&sock); return FAIL; } if( FAIL == zbx_tcp_recv(&sock, &answer)) { zabbix_log( LOG_LEVEL_WARNING, "Error while receiving answer from Node [%s:%d]", CONFIG_MASTER_IP, CONFIG_MASTER_PORT); zbx_tcp_close(&sock); return FAIL; } zabbix_log( LOG_LEVEL_DEBUG, "Answer [%s]", answer); if(strcmp(answer,"OK") == 0) { zabbix_log( LOG_LEVEL_DEBUG, "OK"); ret = SUCCEED; } else { zabbix_log( LOG_LEVEL_WARNING, "NOT OK"); } zbx_tcp_close(&sock); return ret; }
/* * Example: telnet.run["ls /"] */ static int telnet_run(DC_ITEM *item, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "telnet_run"; zbx_sock_t s; int ret = NOTSUPPORTED, flags; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "cannot connect to TELNET server: %s", zbx_tcp_strerror())); goto close; } flags = fcntl(s.socket, F_GETFL); if (0 == (flags & O_NONBLOCK)) fcntl(s.socket, F_SETFL, flags | O_NONBLOCK); if (FAIL == telnet_login(s.socket, item->username, item->password, result)) goto tcp_close; if (FAIL == telnet_execute(s.socket, item->params, result, encoding)) goto tcp_close; ret = SUCCEED; tcp_close: zbx_tcp_close(&s); close: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static int check_ssh(const char *host, unsigned short port, int timeout, int *value_int) { int ret; zbx_sock_t s; char send_buf[MAX_STRING_LEN], *recv_buf, *ssh_server, *ssh_proto; *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout))) { if (SUCCEED == (ret = zbx_tcp_recv(&s, &recv_buf))) { if (0 == strncmp(recv_buf, "SSH", 3)) { ssh_server = ssh_proto = recv_buf + 4; ssh_server += strspn(ssh_proto, "0123456789-. "); ssh_server[-1] = '\0'; zbx_snprintf(send_buf, sizeof(send_buf), "SSH-%s-%s\n", ssh_proto, "zabbix_agent"); *value_int = 1; } else zbx_snprintf(send_buf, sizeof(send_buf), "0\n"); ret = zbx_tcp_send_raw(&s, send_buf); } zbx_tcp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "SSH check error: %s", zbx_tcp_strerror()); return SYSINFO_RET_OK; }
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; }
static int check_ssh(const char *host, unsigned short port, int timeout, int *value_int) { int ret, major, minor; zbx_socket_t s; char send_buf[MAX_STRING_LEN]; const char *buf; *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout, ZBX_TCP_SEC_UNENCRYPTED, NULL, NULL))) { while (NULL != (buf = zbx_tcp_recv_line(&s))) { /* parse buf for SSH identification string as per RFC 4253, section 4.2 */ if (2 == sscanf(buf, "SSH-%d.%d-%*s", &major, &minor)) { zbx_snprintf(send_buf, sizeof(send_buf), "SSH-%d.%d-zabbix_agent\r\n", major, minor); *value_int = 1; break; } } if (0 == *value_int) strscpy(send_buf, "0\n"); ret = zbx_tcp_send_raw(&s, send_buf); zbx_tcp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "SSH check error: %s", zbx_socket_strerror()); return SYSINFO_RET_OK; }
static int check_telnet(const char *host, unsigned short port, int timeout, int *value_int) { zbx_socket_t s; #ifdef _WINDOWS u_long argp = 1; #else int flags; #endif *value_int = 0; if (SUCCEED == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout, ZBX_TCP_SEC_UNENCRYPTED, NULL, NULL)) { #ifdef _WINDOWS ioctlsocket(s.socket, FIONBIO, &argp); /* non-zero value sets the socket to non-blocking */ #else flags = fcntl(s.socket, F_GETFL); if (0 == (flags & O_NONBLOCK)) fcntl(s.socket, F_SETFL, flags | O_NONBLOCK); #endif if (SUCCEED == telnet_test_login(s.socket)) *value_int = 1; else zabbix_log(LOG_LEVEL_DEBUG, "Telnet check error: no login prompt"); zbx_tcp_close(&s); } else zabbix_log(LOG_LEVEL_DEBUG, "%s error: %s", __func__, zbx_socket_strerror()); return SYSINFO_RET_OK; }
int check_ntp(char *host, unsigned short port, int timeout, int *value_int) { zbx_sock_t s; int ret; char *buf = NULL, packet[NTP_PACKET_MIN]; ntp_data data; *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout))) { make_packet(&data); pack_ntp((unsigned char *)packet, sizeof(packet), &data); if (SUCCEED == (ret = zbx_tcp_send_raw(&s, packet))) { if (SUCCEED == (ret = zbx_tcp_recv(&s, &buf))) { unpack_ntp(&data, (unsigned char *)buf, (int)strlen(buf)); *value_int = (0 < data.receive ? (int)(data.receive - ZBX_JAN_1970_IN_SEC) : 0); } } zbx_tcp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_tcp_strerror()); return SYSINFO_RET_OK; }
static void disconnect_proxy(zbx_socket_t *sock) { const char *__function_name = "disconnect_proxy"; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_tcp_close(sock); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
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; }
int zbx_module_unifi_proxy(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret; int i, p, np; zbx_sock_t s; char send_buf[MAX_STRING_LEN]; *send_buf='\0'; np = request->nparam; if (9 < request->nparam) { /* set optional error message */ SET_MSG_RESULT(result, strdup("So much parameters given.")); return SYSINFO_RET_FAIL; } // make request string by concatenate all params for (i=0; i < np; i++) { strcat(send_buf, get_rparam(request, i)); p=strlen(send_buf); send_buf[p]=(i < (np-1)) ? ',' : '\n'; send_buf[p+1]='\0'; } // Connect to UniFi Proxy // item_timeout or (item_timeout-1) ? if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, UNIFI_PROXY_SERVER, UNIFI_PROXY_PORT, CONFIG_TIMEOUT))) { // Send request if (SUCCEED == (ret = zbx_tcp_send_raw(&s, send_buf))) { // Recive answer from UniFi Proxy if (SUCCEED == (ret = zbx_tcp_recv(&s))) { zbx_rtrim(s.buffer, "\r\n"); SET_STR_RESULT(result, strdup(s.buffer)); } } zbx_tcp_close(&s); } if (FAIL == ret) { zabbix_log(LOG_LEVEL_DEBUG, "%s: communication error: %s", ZBX_MODULE_NAME, zbx_tcp_strerror()); SET_MSG_RESULT(result, strdup(zbx_tcp_strerror())); return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
void zbx_mock_test_entry(void **state) { #define ZBX_TCP_HEADER_DATALEN_LEN 13 char *buffer; zbx_socket_t s; ssize_t received; int expected_ret; ZBX_UNUSED(state); zbx_mock_assert_result_eq("zbx_tcp_connect() return code", SUCCEED, zbx_tcp_connect(&s, NULL, "127.0.0.1", 10050, 0, ZBX_TCP_SEC_UNENCRYPTED, NULL, NULL)); expected_ret = zbx_mock_str_to_return_code(zbx_mock_get_parameter_string("out.return")); received = zbx_tcp_recv_ext(&s, 0); if (FAIL == expected_ret) { zbx_mock_assert_result_eq("zbx_tcp_recv_ext() return code", FAIL, received); zbx_tcp_close(&s); return; } zbx_mock_assert_result_eq("zbx_tcp_recv_ext() return code", SUCCEED, SUCCEED_OR_FAIL(received)); zbx_mock_assert_uint64_eq("Received bytes", zbx_mock_get_parameter_uint64("out.bytes"), received); if (0 == received) return; buffer = zbx_yaml_assemble_binary_sequence("out.fragments", received); if (0 != memcmp(buffer + ZBX_TCP_HEADER_DATALEN_LEN, s.buffer, received - ZBX_TCP_HEADER_DATALEN_LEN)) fail_msg("Received message mismatch expected"); zbx_tcp_close(&s); zbx_free(buffer); #undef ZBX_TCP_HEADER_DATALEN_LEN }
/* * 0 - NOT OK * 1 - OK * */ int tcp_expect( const char *host, unsigned short port, const char *request, const char *expect, const char *sendtoclose, int *value_int ) { zbx_sock_t s; char *buf; int ret; assert(value_int); *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 3/*alarm!!!*/))) { if( NULL == request ) { *value_int = 1; } else if( SUCCEED == (ret = zbx_tcp_send_raw(&s, request)) ) { if( NULL == expect ) { *value_int = 1; } else if( SUCCEED == (ret = zbx_tcp_recv(&s, &buf)) ) { if( 0 == strncmp(buf, expect, strlen(expect)) ) { *value_int = 1; } } if(SUCCEED == ret && NULL != sendtoclose) { /* ret = (skip errors) */ zbx_tcp_send_raw(&s, sendtoclose); } } } zbx_tcp_close(&s); if( FAIL == ret ) { zabbix_log(LOG_LEVEL_DEBUG, "TCP expect error: %s", zbx_tcp_strerror()); } return SYSINFO_RET_OK; }
int tcp_expect(const char *host, unsigned short port, int timeout, const char *request, int (*validate_func)(const char *), const char *sendtoclose, int *value_int) { zbx_socket_t s; const char *buf; int net, val = ZBX_TCP_EXPECT_OK; *value_int = 0; if (SUCCEED != (net = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout, ZBX_TCP_SEC_UNENCRYPTED, NULL, NULL))) { goto out; } if (NULL != request) net = zbx_tcp_send_raw(&s, request); if (NULL != validate_func && SUCCEED == net) { val = ZBX_TCP_EXPECT_FAIL; while (NULL != (buf = zbx_tcp_recv_line(&s))) { val = validate_func(buf); if (ZBX_TCP_EXPECT_OK == val) break; if (ZBX_TCP_EXPECT_FAIL == val) { zabbix_log(LOG_LEVEL_DEBUG, "TCP expect content error, received [%s]", buf); break; } } } if (NULL != sendtoclose && SUCCEED == net && ZBX_TCP_EXPECT_OK == val) (void)zbx_tcp_send_raw(&s, sendtoclose); if (SUCCEED == net && ZBX_TCP_EXPECT_OK == val) *value_int = 1; zbx_tcp_close(&s); out: if (SUCCEED != net) zabbix_log(LOG_LEVEL_DEBUG, "TCP expect network error: %s", zbx_socket_strerror()); return SYSINFO_RET_OK; }
/****************************************************************************** * * * Function: send_script * * * * Purpose: sending command to slave node * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * ******************************************************************************/ static int send_script(int nodeid, const char *data, char **result) { DB_RESULT db_result; DB_ROW db_row; int ret = FAIL; zbx_sock_t sock; char *answer; zabbix_log(LOG_LEVEL_DEBUG, "In send_script(nodeid:%d)", nodeid); db_result = DBselect( "select ip,port" " from nodes" " where nodeid=%d", nodeid); if (NULL != (db_row = DBfetch(db_result))) { if (SUCCEED == (ret = zbx_tcp_connect(&sock, CONFIG_SOURCE_IP, db_row[0], atoi(db_row[1]), CONFIG_TRAPPER_TIMEOUT))) { if (FAIL == (ret = zbx_tcp_send(&sock, data))) { *result = zbx_dsprintf(*result, "NODE %d: Error while sending data to Node [%d]: %s.", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); goto exit_sock; } if (SUCCEED == (ret = zbx_tcp_recv(&sock, &answer))) *result = zbx_dsprintf(*result, "%s", answer); else *result = zbx_dsprintf(*result, "NODE %d: Error while receiving data from Node [%d]: %s.", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); exit_sock: zbx_tcp_close(&sock); } else *result = zbx_dsprintf(*result, "NODE %d: Unable to connect to Node [%d]: %s.", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); } else *result = zbx_dsprintf(*result, "NODE %d: Unknown Node ID [%d].", CONFIG_NODEID, nodeid); DBfree_result(db_result); return ret; }
int check_ntp(char *host, unsigned short port, int *value_int) { zbx_sock_t s; int ret; char *buf = NULL; ntp_data data; char packet[NTP_PACKET_MIN]; assert(value_int); *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 0))) { make_packet(&data); pack_ntp((unsigned char*)packet, sizeof(packet), &data); if( SUCCEED == (ret = zbx_tcp_send_raw(&s, packet)) ) { if( SUCCEED == (ret = zbx_tcp_recv(&s, &buf)) ) { unpack_ntp(&data, (unsigned char *)buf, (int)strlen(buf)); #if OFF /* local time */ *value_int = time(NULL); #else /* server time */ *value_int = (data.receive > 0) ? (int)(data.receive - ZBX_JAN_1970_IN_SEC) : 0; #endif } } } zbx_tcp_close(&s); if( FAIL == ret ) { zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_tcp_strerror()); } return SYSINFO_RET_OK; }
/* * 0 - NOT OK * 1 - OK * */ int tcp_expect(const char *host, unsigned short port, int timeout, const char *request, const char *expect, const char *sendtoclose, int *value_int) { zbx_sock_t s; char *buf; int net, val = SUCCEED; *value_int = 0; if (SUCCEED == (net = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout))) { if (NULL != request) net = zbx_tcp_send_raw(&s, request); if (NULL != expect && SUCCEED == net) { if (SUCCEED == (net = zbx_tcp_recv(&s, &buf))) { if (0 != strncmp(buf, expect, strlen(expect))) { val = FAIL; } } } if (NULL != sendtoclose && SUCCEED == net && SUCCEED == val) zbx_tcp_send_raw(&s, sendtoclose); if (SUCCEED == net && SUCCEED == val) *value_int = 1; zbx_tcp_close(&s); } if (FAIL == net) zabbix_log(LOG_LEVEL_DEBUG, "TCP expect network error: %s", zbx_tcp_strerror()); if (FAIL == val) zabbix_log(LOG_LEVEL_DEBUG, "TCP expect content error: expected [%s] received [%s]", expect, buf); return SYSINFO_RET_OK; }
static ZBX_THREAD_ENTRY(send_value, args) { ZBX_THREAD_SENDVAL_ARGS *sentdval_args; zbx_sock_t sock; char *answer = NULL; int tcp_ret, ret = FAIL; assert(args); assert(((zbx_thread_args_t *)args)->args); sentdval_args = (ZBX_THREAD_SENDVAL_ARGS *)((zbx_thread_args_t *)args)->args; #if !defined(_WINDOWS) signal(SIGINT, send_signal_handler); signal(SIGTERM, send_signal_handler); signal(SIGQUIT, send_signal_handler); signal(SIGALRM, send_signal_handler); #endif if (SUCCEED == (tcp_ret = zbx_tcp_connect(&sock, CONFIG_SOURCE_IP, sentdval_args->server, sentdval_args->port, GET_SENDER_TIMEOUT))) { if (SUCCEED == (tcp_ret = zbx_tcp_send(&sock, sentdval_args->json.buffer))) { if (SUCCEED == (tcp_ret = zbx_tcp_recv(&sock, &answer))) { zabbix_log(LOG_LEVEL_DEBUG, "answer [%s]", answer); if (NULL == answer || SUCCEED != check_response(answer)) zabbix_log(LOG_LEVEL_WARNING, "incorrect answer from server [%s]", answer); else ret = SUCCEED; } } zbx_tcp_close(&sock); } if (FAIL == tcp_ret) zabbix_log(LOG_LEVEL_DEBUG, "send value error: %s", zbx_tcp_strerror()); zbx_thread_exit(ret); }
/****************************************************************************** * * * Function: refresh_active_checks * * * * Purpose: Retrive from ZABBIX server list of active checks * * * * Parameters: host - IP or Hostname of ZABBIX server * * port - port of ZABBIX server * * * * Return value: returns SUCCEED on succesfull parsing, * * FAIL on other cases * * * * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol) * * * * Comments: * * * ******************************************************************************/ static int refresh_active_checks(const char *host, unsigned short port) { zbx_sock_t s; char *buf; int ret; struct zbx_json json; zabbix_log( LOG_LEVEL_DEBUG, "refresh_active_checks('%s',%u)", host, port); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST, CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, CONFIG_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", json.buffer); if (SUCCEED == (ret = zbx_tcp_send(&s, json.buffer))) { zabbix_log(LOG_LEVEL_DEBUG, "Before read"); if (SUCCEED == (ret = zbx_tcp_recv_ext(&s, &buf, ZBX_TCP_READ_UNTIL_CLOSE))) { zabbix_log(LOG_LEVEL_DEBUG, "Got [%s]", buf); parse_list_of_checks(buf); } } zbx_tcp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "Get active checks error: %s", zbx_tcp_strerror()); zbx_json_free(&json); return ret; }
static int get_http_page(const char *host, const char *path, unsigned short port, char *buffer, int max_buffer_len) { int ret; char *recv_buffer; char request[MAX_STRING_LEN]; zbx_sock_t s; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, CONFIG_TIMEOUT))) { zbx_snprintf(request, sizeof(request), "GET /%s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n" "\r\n", path, host); if (SUCCEED == (ret = zbx_tcp_send_raw(&s, request))) { if (SUCCEED == (ret = zbx_tcp_recv_ext(&s, &recv_buffer, ZBX_TCP_READ_UNTIL_CLOSE, 0))) { if (NULL != buffer) zbx_strlcpy(buffer, recv_buffer, max_buffer_len); } } zbx_tcp_close(&s); } if (FAIL == ret) { zabbix_log(LOG_LEVEL_DEBUG, "HTTP get error: %s", zbx_tcp_strerror()); return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
int zbx_module_redis_ping(AGENT_REQUEST *request, AGENT_RESULT *result) { char *CONFIG_SOURCE_IP = NULL; zbx_sock_t s; char *rs_host, *str_rs_port; unsigned int rs_port; const char *buf; char rv[MAX_STRING_LEN]; int rs_status = 0; time_t now; char str_time[MAX_STRING_LEN]; char cmd[MAX_STRING_LEN]; char hv[MAX_STRING_LEN]; struct tm *tm = NULL; if (request->nparam == 2) { rs_host = get_rparam(request, 0); str_rs_port = get_rparam(request, 1); rs_port = atoi(str_rs_port); } else if (request->nparam == 1) { rs_host = REDIS_DEFAULT_INSTANCE_HOST; str_rs_port = get_rparam(request, 0); rs_port = atoi(str_rs_port); } else { /* set optional error message */ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters")); return SYSINFO_RET_FAIL; } /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], args:[%s,%d]", rs_host, rs_port); */ time(&now); tm = localtime(&now); strftime(str_time, MAX_STRING_LEN, "%Y%m%d%H%M%S", tm); /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], str_time:[%s]", str_time); */ zbx_snprintf(cmd, MAX_STRING_LEN, "set ZBX_PING %s\r\nget ZBX_PING\r\nquit\r\n",str_time); zbx_snprintf(hv, MAX_STRING_LEN, "+OK$%d%s+OK", strlen(str_time), str_time); if (SUCCEED == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, rs_host, rs_port, 0)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], connect to [%s:%d] successful", rs_host, rs_port); */ if (SUCCEED == zbx_tcp_send_raw(&s, cmd)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], send request successful"); */ strscpy(rv, ""); while (NULL != (buf = zbx_tcp_recv_line(&s))) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], get [%s]", buf); */ zbx_strlcat(rv, buf, MAX_STRING_LEN); } /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], all get [%s]", rv); */ if (0 == strcmp(rv, hv)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], redis instance:[%s:%d] is up", rs_host, rs_port); */ rs_status = 1; } } zbx_tcp_close(&s); } if (rs_status == 1) { SET_UI64_RESULT(result, 1); } else { SET_UI64_RESULT(result, 0); } return SYSINFO_RET_OK; }
int zbx_module_redis_status(AGENT_REQUEST *request, AGENT_RESULT *result) { char *CONFIG_SOURCE_IP = NULL; zbx_sock_t s; char *rs_host, *str_rs_port, *key; unsigned int rs_port; char rs_st_name[MAX_STRING_LEN]; zbx_uint64_t rs_st_value; const char *buf; char *tmp; char *p; int ret = SYSINFO_RET_FAIL; int find = 0; int net_error = 0; if (request->nparam == 3) { rs_host = get_rparam(request, 0); str_rs_port = get_rparam(request, 1); rs_port = atoi(str_rs_port); key = get_rparam(request, 2); } else if (request->nparam == 2) { rs_host = REDIS_DEFAULT_INSTANCE_HOST; str_rs_port = get_rparam(request, 0); rs_port = atoi(str_rs_port); key = get_rparam(request, 1); } else { /* set optional error message */ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters")); return ret; } /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], args:[%s,%d]", rs_host, rs_port); */ if (SUCCEED == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, rs_host, rs_port, 0)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], connect to [%s:%d] successful", rs_host, rs_port); */ if (SUCCEED == zbx_tcp_send_raw(&s, "info\r\nquit\r\n")) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], send request successful"); */ while (NULL != (buf = zbx_tcp_recv_line(&s))) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], got [%s]", buf); */ if (2 == sscanf(buf, "%[^:]:" ZBX_FS_UI64, rs_st_name, &rs_st_value)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], parse result name :[%s] value:[%d]", rs_st_name, rs_st_value); */ if (0 == strcmp(rs_st_name, key)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], args:[%d,%s] value:[%d]", rs_port, key, rs_st_value); */ find = 1; SET_UI64_RESULT(result, rs_st_value); ret = SYSINFO_RET_OK; break; } } } } else { net_error = 1; zabbix_log(LOG_LEVEL_WARNING, "module [redis], func [zbx_module_redis_status],get redis status error: [%s]", zbx_tcp_strerror()); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Get redis status error [%s]", zbx_tcp_strerror())); } zbx_tcp_close(&s); } else { net_error = 1; zabbix_log(LOG_LEVEL_WARNING, "module [redis], func [zbx_module_redis_status], connect to redis error: [%s]", zbx_tcp_strerror()); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Connect to redis error [%s]", zbx_tcp_strerror())); } if (find != 1 && net_error == 0) { zabbix_log(LOG_LEVEL_WARNING, "module [redis], func [zbx_module_redis_status], can't find key: [%s]", key); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Not supported key [%s]", key)); } return ret; }
/* * Send email */ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,char *mailsubject,char *mailbody, char *error, int max_error_len) { int ret=SUCCEED; zbx_sock_t s; int i,e; char c[MAX_STRING_LEN], *cp = NULL; char str_time[MAX_STRING_LEN]; struct tm *local_time = NULL; time_t email_time; char *OK_220="220"; char *OK_250="250"; char *OK_251="251"; char *OK_354="354"; zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]", smtp_server); if(FAIL == zbx_tcp_connect(&s, smtp_server, 25, 0, NULL)) { zbx_snprintf(error,max_error_len,"Cannot connect to SMTP server [%s] [%s]", smtp_server, zbx_tcp_strerror()); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving initial string from SMTP server [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_220,c,strlen(OK_220)) != 0) { zbx_snprintf(error,max_error_len,"No welcome message 220* from SMTP server [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strlen(smtp_helo) != 0) { memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"HELO %s\r\n",smtp_helo); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending HELO to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving answer on HELO request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_250,c,strlen(OK_250)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on HELO [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s",error); zabbix_syslog("%s",error); ret=FAIL; goto out; } } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"MAIL FROM: <%s>\r\n",smtp_email); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending MAIL FROM to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving answer on MAIL FROM request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_250,c,strlen(OK_250)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on MAIL FROM [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"RCPT TO: <%s>\r\n",mailto); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending RCPT TO to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving answer on RCPT TO request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } /* May return 251 as well: User not local; will forward to <forward-path>. See RFC825 */ if( strncmp(OK_250,c,strlen(OK_250)) != 0 && strncmp(OK_251,c,strlen(OK_251)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on RCPT TO [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"DATA\r\n"); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending DATA to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receivng answer on DATA request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_354,c,strlen(OK_354)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on DATA [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } cp = string_replace(mailsubject, "\r\n", "\n"); mailsubject = string_replace(cp, "\n", "\r\n"); zbx_free(cp); cp = string_replace(mailbody, "\r\n", "\n"); mailbody = string_replace(cp, "\n", "\r\n"); zbx_free(cp); memset(c,0,MAX_STRING_LEN); time(&email_time); local_time = localtime(&email_time); strftime( str_time, MAX_STRING_LEN, "%a, %d %b %Y %H:%M:%S %z", local_time ); cp = zbx_dsprintf(cp,"From:<%s>\r\nTo:<%s>\r\nDate: %s\r\nSubject: %s\r\n\r\n%s",smtp_email,mailto,str_time,mailsubject, mailbody); e=write(s.socket,cp,strlen(cp)); zbx_free(cp); zbx_free(mailsubject); zbx_free(mailbody); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending mail subject and body to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"\r\n.\r\n"); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending . to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receivng answer on . request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_250,c,strlen(OK_250)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on end of data [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"QUIT\r\n"); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending QUIT to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } out: zbx_tcp_close(&s); return ret; }
void get_values_java(unsigned char request, DC_ITEM *items, AGENT_RESULT *results, int *errcodes, int num) { const char *__function_name = "get_values_java"; zbx_sock_t s; struct zbx_json json; char error[MAX_STRING_LEN]; char *buffer = NULL; int i, j, err = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' addr:'%s' num:%d", __function_name, items[0].host.host, items[0].interface.addr, num); for (j = 0; j < num; j++) /* locate first supported item */ { if (SUCCEED == errcodes[j]) break; } if (j == num) /* all items already NOTSUPPORTED (with invalid key or port) */ goto out; zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); if (NULL == CONFIG_JAVA_GATEWAY || '\0' == *CONFIG_JAVA_GATEWAY) { err = GATEWAY_ERROR; strscpy(error, "JavaGateway configuration parameter not set or empty"); goto exit; } if (ZBX_JAVA_GATEWAY_REQUEST_INTERNAL == request) { zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_JAVA_GATEWAY_INTERNAL, ZBX_JSON_TYPE_STRING); } else if (ZBX_JAVA_GATEWAY_REQUEST_JMX == request) { for (i = j + 1; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (0 != strcmp(items[j].interface.addr, items[i].interface.addr) || items[j].interface.port != items[i].interface.port || 0 != strcmp(items[j].username, items[i].username) || 0 != strcmp(items[j].password, items[i].password)) { err = GATEWAY_ERROR; strscpy(error, "Java poller received items with different connection parameters"); goto exit; } } zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_JAVA_GATEWAY_JMX, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_CONN, items[j].interface.addr, ZBX_JSON_TYPE_STRING); zbx_json_adduint64(&json, ZBX_PROTO_TAG_PORT, items[j].interface.port); if ('\0' != *items[j].username) zbx_json_addstring(&json, ZBX_PROTO_TAG_USERNAME, items[j].username, ZBX_JSON_TYPE_STRING); if ('\0' != *items[j].password) zbx_json_addstring(&json, ZBX_PROTO_TAG_PASSWORD, items[j].password, ZBX_JSON_TYPE_STRING); } else assert(0); zbx_json_addarray(&json, ZBX_PROTO_TAG_KEYS); for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; zbx_json_addstring(&json, NULL, items[i].key, ZBX_JSON_TYPE_STRING); } zbx_json_close(&json); if (SUCCEED == (err = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, CONFIG_JAVA_GATEWAY, CONFIG_JAVA_GATEWAY_PORT, CONFIG_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON before sending [%s]", json.buffer); if (SUCCEED == (err = zbx_tcp_send(&s, json.buffer))) { if (SUCCEED == (err = zbx_tcp_recv(&s, &buffer))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON back [%s]", buffer); err = parse_response(items, results, errcodes, num, buffer, error, sizeof(error)); } } zbx_tcp_close(&s); } zbx_json_free(&json); if (FAIL == err) { strscpy(error, zbx_tcp_strerror()); err = GATEWAY_ERROR; } exit: if (NETWORK_ERROR == err || GATEWAY_ERROR == err) { zabbix_log(LOG_LEVEL_DEBUG, "Getting Java values failed: %s", error); for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (!ISSET_MSG(&results[i])) { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error)); errcodes[i] = err; } } } out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
void disconnect_server(zbx_sock_t *sock) { zbx_tcp_close(sock); }
/****************************************************************************** * * * Function: get_value_agent * * * * Purpose: retrieve data from Zabbix agent * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NETWORK_ERROR - network related error occurred * * NOTSUPPORTED - item not supported by the agent * * AGENT_ERROR - uncritical error on agent side occurred * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: error will contain error message * * * ******************************************************************************/ int get_value_agent(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_agent"; zbx_socket_t s; char buffer[MAX_STRING_LEN]; int ret = SUCCEED; ssize_t received_len; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' addr:'%s' key:'%s'", __function_name, item->host.host, item->interface.addr, item->key); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0))) { zbx_snprintf(buffer, sizeof(buffer), "%s\n", item->key); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", buffer); /* send requests using old protocol */ if (SUCCEED != zbx_tcp_send_raw(&s, buffer)) ret = NETWORK_ERROR; else if (FAIL != (received_len = zbx_tcp_recv_ext(&s, ZBX_TCP_READ_UNTIL_CLOSE, 0))) ret = SUCCEED; else ret = TIMEOUT_ERROR; } else ret = NETWORK_ERROR; if (SUCCEED == ret) { zbx_rtrim(s.buffer, " \r\n"); zbx_ltrim(s.buffer, " "); zabbix_log(LOG_LEVEL_DEBUG, "get value from agent result: '%s'", s.buffer); if (0 == strcmp(s.buffer, ZBX_NOTSUPPORTED)) { /* 'ZBX_NOTSUPPORTED\0<error message>' */ if (sizeof(ZBX_NOTSUPPORTED) < s.read_bytes) zbx_snprintf(buffer, sizeof(buffer), "%s", s.buffer + sizeof(ZBX_NOTSUPPORTED)); else zbx_snprintf(buffer, sizeof(buffer), "Not supported by Zabbix Agent"); SET_MSG_RESULT(result, strdup(buffer)); ret = NOTSUPPORTED; } else if (0 == strcmp(s.buffer, ZBX_ERROR)) { zbx_snprintf(buffer, sizeof(buffer), "Zabbix Agent non-critical error"); SET_MSG_RESULT(result, strdup(buffer)); ret = AGENT_ERROR; } else if (0 == received_len) { zbx_snprintf(buffer, sizeof(buffer), "Received empty response from Zabbix Agent at [%s]." " Assuming that agent dropped connection because of access permissions.", item->interface.addr); SET_MSG_RESULT(result, strdup(buffer)); ret = NETWORK_ERROR; } else if (SUCCEED != set_result_type(result, item->value_type, item->data_type, s.buffer)) ret = NOTSUPPORTED; } else { zbx_snprintf(buffer, sizeof(buffer), "Get value from agent failed: %s", zbx_socket_strerror()); SET_MSG_RESULT(result, strdup(buffer)); } zbx_tcp_close(&s); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/* example ssh.run["ls /"] */ static int ssh_run(DC_ITEM *item, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "ssh_run"; zbx_sock_t s; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int auth_pw = 0, rc, ret = NOTSUPPORTED, exitcode, bytecount = 0; char buffer[MAX_BUFFER_LEN], buf[16], *userauthlist, *publickey = NULL, *privatekey = NULL, *ssherr; size_t sz; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot connect to SSH server: %s", zbx_tcp_strerror())); goto close; } /* initializes an SSH session object */ if (NULL == (session = libssh2_session_init())) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot initialize SSH session")); goto tcp_close; } /* set blocking mode on session */ libssh2_session_set_blocking(session, 1); /* Create a session instance and start it up. This will trade welcome */ /* banners, exchange keys, and setup crypto, compression, and MAC layers */ if (0 != libssh2_session_startup(session, s.socket)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot establish SSH session: %s", ssherr)); goto session_free; } /* check what authentication methods are available */ if (NULL != (userauthlist = libssh2_userauth_list(session, item->username, strlen(item->username)))) { if (NULL != strstr(userauthlist, "password")) auth_pw |= 1; if (NULL != strstr(userauthlist, "keyboard-interactive")) auth_pw |= 2; if (NULL != strstr(userauthlist, "publickey")) auth_pw |= 4; } else { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain authentication methods: %s", ssherr)); goto session_close; } zabbix_log(LOG_LEVEL_DEBUG, "%s() supported authentication methods:'%s'", __function_name, userauthlist); switch (item->authtype) { case ITEM_AUTHTYPE_PASSWORD: if (auth_pw & 1) { /* we could authenticate via password */ if (0 != libssh2_userauth_password(session, item->username, item->password)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Password authentication failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() password authentication succeeded", __function_name); } else if (auth_pw & 2) { /* or via keyboard-interactive */ password = item->password; if (0 != libssh2_userauth_keyboard_interactive(session, item->username, &kbd_callback)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Keyboard-interactive authentication" " failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() keyboard-interactive authentication succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; case ITEM_AUTHTYPE_PUBLICKEY: if (auth_pw & 4) { if (NULL == CONFIG_SSH_KEY_LOCATION) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Authentication by public key failed." " SSHKeyLocation option is not set")); goto session_close; } /* or by public key */ publickey = zbx_dsprintf(publickey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->publickey); privatekey = zbx_dsprintf(privatekey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->privatekey); if (SUCCEED != zbx_is_regular_file(publickey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access public key file %s", publickey)); goto session_close; } if (SUCCEED != zbx_is_regular_file(privatekey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access private key file %s", privatekey)); goto session_close; } rc = libssh2_userauth_publickey_fromfile(session, item->username, publickey, privatekey, item->password); zbx_free(publickey); zbx_free(privatekey); if (0 != rc) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Public key authentication failed:" " %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() authentication by public key succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; } /* exec non-blocking on the remove host */ while (NULL == (channel = libssh2_channel_open_session(session))) { switch (libssh2_session_last_error(session, NULL, NULL, 0)) { /* marked for non-blocking I/O but the call would block. */ case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot establish generic session channel")); goto session_close; } } dos2unix(item->params); /* CR+LF (Windows) => LF (Unix) */ /* request a shell on a channel and execute command */ while (0 != (rc = libssh2_channel_exec(channel, item->params))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot request a shell")); goto channel_close; } } for (;;) { /* loop until we block */ do { if (0 < (rc = libssh2_channel_read(channel, buf, sizeof(buf)))) { sz = (size_t)rc; if (sz > MAX_BUFFER_LEN - (bytecount + 1)) sz = MAX_BUFFER_LEN - (bytecount + 1); if (0 == sz) continue; memcpy(buffer + bytecount, buf, sz); bytecount += sz; } } while (rc > 0); /* this is due to blocking that would occur otherwise so we loop on * this condition */ if (LIBSSH2_ERROR_EAGAIN == rc) waitsocket(s.socket, session); else if (rc < 0) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read data from SSH server")); goto channel_close; } else break; } buffer[bytecount] = '\0'; SET_STR_RESULT(result, convert_to_utf8(buffer, bytecount, encoding)); ret = SYSINFO_RET_OK; channel_close: /* close an active data channel */ exitcode = 127; while (0 != (rc = libssh2_channel_close(channel))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: libssh2_session_last_error(session, &ssherr, NULL, 0); zabbix_log(LOG_LEVEL_WARNING, "%s() cannot close generic session channel: %s", __function_name, ssherr); break; } } if (0 == rc) exitcode = libssh2_channel_get_exit_status(channel); zabbix_log(LOG_LEVEL_DEBUG, "%s() exitcode: %d bytecount: %d", __function_name, exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; session_close: libssh2_session_disconnect(session, "Normal Shutdown"); session_free: libssh2_session_free(session); tcp_close: zbx_tcp_close(&s); close: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
void disconnect_node(zbx_sock_t *sock) { zbx_tcp_close(sock); }
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; }
/****************************************************************************** * * * Function: send_buffer * * * * Purpose: Send value stgored in the buffer to ZABBIX server * * * * Parameters: host - IP or Hostname of ZABBIX server * * port - port number * * * * Return value: returns SUCCEED on succesfull parsing, * * FAIL on other cases * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int send_buffer( const char *host, unsigned short port ) { zbx_sock_t s; char *buf = NULL; int ret = SUCCEED; struct zbx_json json; int i; static int lastsent = 0; int now; zabbix_log( LOG_LEVEL_DEBUG, "In send_buffer('%s','%d')", host, port); zabbix_log( LOG_LEVEL_DEBUG, "Values in the buffer %d Max %d", buffer.count, CONFIG_BUFFER_SIZE); now = (int)time(NULL); if(buffer.count < CONFIG_BUFFER_SIZE && now-lastsent < CONFIG_BUFFER_SEND) { zabbix_log( LOG_LEVEL_DEBUG, "Will not send now. Now %d lastsent %d < %d", now, lastsent, CONFIG_BUFFER_SEND); return ret; } if(buffer.count < 1) { return ret; } zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_AGENT_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for(i=0;i<buffer.count;i++) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST, buffer.data[i].host, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, buffer.data[i].key, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_VALUE, buffer.data[i].value, ZBX_JSON_TYPE_STRING); if (buffer.data[i].lastlogsize) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGLASTSIZE, buffer.data[i].lastlogsize); if (buffer.data[i].timestamp) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGTIMESTAMP, buffer.data[i].timestamp); if (buffer.data[i].source) zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGSOURCE, buffer.data[i].source, ZBX_JSON_TYPE_STRING); if (buffer.data[i].severity) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGSEVERITY, buffer.data[i].severity); zbx_json_adduint64(&json, ZBX_PROTO_TAG_CLOCK, buffer.data[i].clock); zbx_json_close(&json); } zbx_json_close(&json); zbx_json_adduint64(&json, ZBX_PROTO_TAG_CLOCK, (int)time(NULL)); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, MIN(buffer.count*CONFIG_TIMEOUT, 60)))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON before sending [%s]", json.buffer); ret = zbx_tcp_send(&s, json.buffer); if( SUCCEED == ret ) { if( SUCCEED == (ret = zbx_tcp_recv(&s, &buf)) ) { zabbix_log(LOG_LEVEL_DEBUG, "JSON back [%s]", buf); if( !buf || check_response(buf) != SUCCEED ) { zabbix_log(LOG_LEVEL_DEBUG, "NOT OK"); } else { zabbix_log(LOG_LEVEL_DEBUG, "OK"); } } else zabbix_log(LOG_LEVEL_DEBUG, "Send value error: [recv] %s", zbx_tcp_strerror()); } else zabbix_log(LOG_LEVEL_DEBUG, "Send value error: [send] %s", zbx_tcp_strerror()); zbx_tcp_close(&s); } else zabbix_log(LOG_LEVEL_DEBUG, "Send value error: [connect] %s", zbx_tcp_strerror()); zbx_json_free(&json); if(SUCCEED == ret) { /* free buffer */ for(i=0;i<buffer.count;i++) { if(buffer.data[i].host != NULL) zbx_free(buffer.data[i].host); if(buffer.data[i].key != NULL) zbx_free(buffer.data[i].key); if(buffer.data[i].value != NULL) zbx_free(buffer.data[i].value); if(buffer.data[i].source != NULL) zbx_free(buffer.data[i].source); } buffer.count = 0; } if(SUCCEED == ret) lastsent = now; return ret; }
static int send_email_plain(const char *smtp_server, unsigned short smtp_port, const char *smtp_helo, const char *from_display_name, const char *from_angle_addr, const char *to_display_name, const char *to_angle_addr, const char *mailsubject, const char *mailbody, int timeout, char *error, size_t max_error_len) { zbx_socket_t s; int err, ret = FAIL; char cmd[MAX_STRING_LEN], *cmdp = NULL; const char *OK_220 = "220"; const char *OK_250 = "250"; const char *OK_251 = "251"; const char *OK_354 = "354"; const char *response; alarm(timeout); /* connect to and receive an initial greeting from SMTP server */ if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, smtp_server, smtp_port, 0)) { zbx_snprintf(error, max_error_len, "cannot connect to SMTP server \"%s\": %s", smtp_server, zbx_socket_strerror()); goto out; } if (FAIL == smtp_readln(&s, &response)) { zbx_snprintf(error, max_error_len, "error receiving initial string from SMTP server: %s", zbx_strerror(errno)); goto close; } if (0 != strncmp(response, OK_220, strlen(OK_220))) { zbx_snprintf(error, max_error_len, "no welcome message 220* from SMTP server \"%s\"", response); goto close; } /* send HELO */ if ('\0' != *smtp_helo) { zbx_snprintf(cmd, sizeof(cmd), "HELO %s\r\n", smtp_helo); if (-1 == write(s.socket, cmd, strlen(cmd))) { zbx_snprintf(error, max_error_len, "error sending HELO to mailserver: %s", zbx_strerror(errno)); goto close; } if (FAIL == smtp_readln(&s, &response)) { zbx_snprintf(error, max_error_len, "error receiving answer on HELO request: %s", zbx_strerror(errno)); goto close; } if (0 != strncmp(response, OK_250, strlen(OK_250))) { zbx_snprintf(error, max_error_len, "wrong answer on HELO \"%s\"", response); goto close; } } /* send MAIL FROM */ zbx_snprintf(cmd, sizeof(cmd), "MAIL FROM:%s\r\n", from_angle_addr); if (-1 == write(s.socket, cmd, strlen(cmd))) { zbx_snprintf(error, max_error_len, "error sending MAIL FROM to mailserver: %s", zbx_strerror(errno)); goto close; } if (FAIL == smtp_readln(&s, &response)) { zbx_snprintf(error, max_error_len, "error receiving answer on MAIL FROM request: %s", zbx_strerror(errno)); goto close; } if (0 != strncmp(response, OK_250, strlen(OK_250))) { zbx_snprintf(error, max_error_len, "wrong answer on MAIL FROM \"%s\"", response); goto close; } /* send RCPT TO */ zbx_snprintf(cmd, sizeof(cmd), "RCPT TO:%s\r\n", to_angle_addr); if (-1 == write(s.socket, cmd, strlen(cmd))) { zbx_snprintf(error, max_error_len, "error sending RCPT TO to mailserver: %s", zbx_strerror(errno)); goto close; } if (FAIL == smtp_readln(&s, &response)) { zbx_snprintf(error, max_error_len, "error receiving answer on RCPT TO request: %s", zbx_strerror(errno)); goto close; } /* May return 251 as well: User not local; will forward to <forward-path>. See RFC825. */ if (0 != strncmp(response, OK_250, strlen(OK_250)) && 0 != strncmp(response, OK_251, strlen(OK_251))) { zbx_snprintf(error, max_error_len, "wrong answer on RCPT TO \"%s\"", response); goto close; } /* send DATA */ zbx_snprintf(cmd, sizeof(cmd), "DATA\r\n"); if (-1 == write(s.socket, cmd, strlen(cmd))) { zbx_snprintf(error, max_error_len, "error sending DATA to mailserver: %s", zbx_strerror(errno)); goto close; } if (FAIL == smtp_readln(&s, &response)) { zbx_snprintf(error, max_error_len, "error receiving answer on DATA request: %s", zbx_strerror(errno)); goto close; } if (0 != strncmp(response, OK_354, strlen(OK_354))) { zbx_snprintf(error, max_error_len, "wrong answer on DATA \"%s\"", response); goto close; } cmdp = smtp_prepare_payload(from_display_name, from_angle_addr, to_display_name, to_angle_addr, mailsubject, mailbody); err = write(s.socket, cmdp, strlen(cmdp)); zbx_free(cmdp); if (-1 == err) { zbx_snprintf(error, max_error_len, "error sending headers and mail body to mailserver: %s", zbx_strerror(errno)); goto close; } /* send . */ zbx_snprintf(cmd, sizeof(cmd), "\r\n.\r\n"); if (-1 == write(s.socket, cmd, strlen(cmd))) { zbx_snprintf(error, max_error_len, "error sending . to mailserver: %s", zbx_strerror(errno)); goto close; } if (FAIL == smtp_readln(&s, &response)) { zbx_snprintf(error, max_error_len, "error receiving answer on . request: %s", zbx_strerror(errno)); goto close; } if (0 != strncmp(response, OK_250, strlen(OK_250))) { zbx_snprintf(error, max_error_len, "wrong answer on end of data \"%s\"", response); goto close; } /* send QUIT */ zbx_snprintf(cmd, sizeof(cmd), "QUIT\r\n"); if (-1 == write(s.socket, cmd, strlen(cmd))) { zbx_snprintf(error, max_error_len, "error sending QUIT to mailserver: %s", zbx_strerror(errno)); goto close; } ret = SUCCEED; close: zbx_tcp_close(&s); out: alarm(0); return ret; }