summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/zbxcomms/comms.c47
-rw-r--r--src/libs/zbxemail/email.c2
-rw-r--r--src/libs/zbxicmpping/icmpping.c73
-rw-r--r--src/libs/zbxsysinfo/common/http.c2
-rw-r--r--src/libs/zbxsysinfo/common/http.h2
-rw-r--r--src/libs/zbxsysinfo/common/net.c12
-rw-r--r--src/libs/zbxsysinfo/common/net.h2
-rw-r--r--src/libs/zbxsysinfo/simple/ntp.c3
-rw-r--r--src/libs/zbxsysinfo/simple/ntp.h2
-rw-r--r--src/libs/zbxsysinfo/simple/simple.c2
-rw-r--r--src/libs/zbxsysinfo/simple/simple.h1
11 files changed, 125 insertions, 23 deletions
diff --git a/src/libs/zbxcomms/comms.c b/src/libs/zbxcomms/comms.c
index 94479bbe..dfb40103 100644
--- a/src/libs/zbxcomms/comms.c
+++ b/src/libs/zbxcomms/comms.c
@@ -317,6 +317,7 @@ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o)
******************************************************************************/
#if defined(HAVE_IPV6)
int zbx_tcp_connect(zbx_sock_t *s,
+ const char *source_ip,
const char *ip,
unsigned short port,
int timeout
@@ -324,6 +325,7 @@ int zbx_tcp_connect(zbx_sock_t *s,
{
int ret = FAIL;
struct addrinfo *ai = NULL, hints;
+ struct addrinfo *ai_bind = NULL;
char service[MAX_STRING_LEN];
ZBX_TCP_START();
@@ -345,6 +347,29 @@ int zbx_tcp_connect(zbx_sock_t *s,
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)
@@ -369,16 +394,21 @@ int zbx_tcp_connect(zbx_sock_t *s,
out:
if (NULL != ai)
freeaddrinfo(ai);
+
+ if (NULL != ai_bind)
+ freeaddrinfo(ai_bind);
+
return ret;
}
#else
int zbx_tcp_connect(zbx_sock_t *s,
+ const char *source_ip,
const char *ip,
unsigned short port,
int timeout
)
{
- ZBX_SOCKADDR servaddr_in;
+ ZBX_SOCKADDR servaddr_in, source_addr;
struct hostent *hp;
ZBX_TCP_START();
@@ -399,6 +429,21 @@ int zbx_tcp_connect(zbx_sock_t *s,
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)
diff --git a/src/libs/zbxemail/email.c b/src/libs/zbxemail/email.c
index af1d7103..9ff5841b 100644
--- a/src/libs/zbxemail/email.c
+++ b/src/libs/zbxemail/email.c
@@ -62,7 +62,7 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]", smtp_server);
- if(FAIL == zbx_tcp_connect(&s, smtp_server, 25, 0))
+ if(FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, smtp_server, 25, 0))
{
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);
diff --git a/src/libs/zbxicmpping/icmpping.c b/src/libs/zbxicmpping/icmpping.c
index cbe62502..983bb16c 100644
--- a/src/libs/zbxicmpping/icmpping.c
+++ b/src/libs/zbxicmpping/icmpping.c
@@ -22,9 +22,10 @@
#include "log.h"
#include "zlog.h"
-extern char *CONFIG_FPING_LOCATION;
+extern char *CONFIG_SOURCE_IP;
+extern char *CONFIG_FPING_LOCATION;
#ifdef HAVE_IPV6
-extern char *CONFIG_FPING6_LOCATION;
+extern char *CONFIG_FPING6_LOCATION;
#endif /* HAVE_IPV6 */
/******************************************************************************
@@ -48,9 +49,14 @@ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count)
FILE *f;
char filename[MAX_STRING_LEN];
char tmp[MAX_STRING_LEN];
- int i;
- char *c;
+ int i, res = FAIL;
+ char *c, source_ip[64];
ZBX_FPING_HOST *host;
+#ifdef HAVE_IPV6
+ struct addrinfo hints, *ai = NULL;
+ char *fping;
+ int e;
+#endif
zabbix_log(LOG_LEVEL_DEBUG, "In do_ping() [hosts_count:%d]",
hosts_count);
@@ -73,15 +79,51 @@ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count)
fclose(f);
+ if (NULL != CONFIG_SOURCE_IP)
+ zbx_snprintf(source_ip, sizeof(source_ip), "-S%s ", CONFIG_SOURCE_IP);
+ else
+ *source_ip = '\0';
+
#ifdef HAVE_IPV6
- zbx_snprintf(tmp, sizeof(tmp), "%s -c3 2>/dev/null <%s;%s -c3 2>/dev/null <%s",
- CONFIG_FPING_LOCATION,
- filename,
- CONFIG_FPING6_LOCATION,
- filename);
+ if (NULL != CONFIG_SOURCE_IP)
+ {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if (0 != (e = getaddrinfo(CONFIG_SOURCE_IP, NULL, &hints, &ai)))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Cannot resolve address [%s], error %d: %s",
+ CONFIG_SOURCE_IP, e, gai_strerror(e));
+ goto out;
+ }
+
+ if (ai->ai_family == PF_INET)
+ fping = CONFIG_FPING_LOCATION;
+ else if (ai->ai_family == PF_INET6)
+ fping = CONFIG_FPING6_LOCATION;
+ else
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Unsupported address family [%s]", CONFIG_SOURCE_IP);
+ goto out;
+ }
+
+ zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s",
+ fping,
+ source_ip,
+ filename);
+ }
+ else
+ zbx_snprintf(tmp, sizeof(tmp), "%s -c3 2>/dev/null <%s;%s -c3 2>/dev/null <%s",
+ CONFIG_FPING_LOCATION,
+ filename,
+ CONFIG_FPING6_LOCATION,
+ filename);
#else /* HAVE_IPV6 */
- zbx_snprintf(tmp, sizeof(tmp), "%s -c3 2>/dev/null <%s",
+ zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s",
CONFIG_FPING_LOCATION,
+ source_ip,
filename);
#endif /* HAVE_IPV6 */
@@ -92,7 +134,7 @@ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count)
zabbix_syslog("Cannot execute [%s] [%s]",
CONFIG_FPING_LOCATION,
strerror(errno));
- return FAIL;
+ goto out;
}
while (NULL != fgets(tmp, sizeof(tmp), f)) {
@@ -123,10 +165,17 @@ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count)
}
pclose(f);
+ res = SUCCEED;
+out:
unlink(filename);
+#ifdef HAVE_IPV6
+ if (NULL != ai)
+ freeaddrinfo(ai);
+#endif
+
zabbix_log(LOG_LEVEL_DEBUG, "End of do_ping()");
- return SUCCEED;
+ return res;
}
diff --git a/src/libs/zbxsysinfo/common/http.c b/src/libs/zbxsysinfo/common/http.c
index 29988756..dec67120 100644
--- a/src/libs/zbxsysinfo/common/http.c
+++ b/src/libs/zbxsysinfo/common/http.c
@@ -40,7 +40,7 @@ static int get_http_page(char *host, char *param, unsigned short port, char *buf
assert(buffer);
- if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0))) {
+ if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 0))) {
zbx_snprintf(request, sizeof(request), "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
param,
host);
diff --git a/src/libs/zbxsysinfo/common/http.h b/src/libs/zbxsysinfo/common/http.h
index 4f0fc118..efeac96b 100644
--- a/src/libs/zbxsysinfo/common/http.h
+++ b/src/libs/zbxsysinfo/common/http.h
@@ -21,6 +21,8 @@
#include "sysinfo.h"
+extern char *CONFIG_SOURCE_IP;
+
int WEB_PAGE_GET(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result);
int WEB_PAGE_PERF(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result);
int WEB_PAGE_REGEXP(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result);
diff --git a/src/libs/zbxsysinfo/common/net.c b/src/libs/zbxsysinfo/common/net.c
index 0dd93dea..d3f336f2 100644
--- a/src/libs/zbxsysinfo/common/net.c
+++ b/src/libs/zbxsysinfo/common/net.c
@@ -31,12 +31,12 @@
* 1 - OK
* */
int tcp_expect(
- const char *host,
+ const char *host,
unsigned short port,
- const char *request,
- const char *expect,
- const char *sendtoclose,
- int *value_int
+ const char *request,
+ const char *expect,
+ const char *sendtoclose,
+ int *value_int
)
{
zbx_sock_t s;
@@ -47,7 +47,7 @@ int tcp_expect(
*value_int = 0;
- if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 3/*alarm!!!*/))) {
+ if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 3/*alarm!!!*/))) {
if( NULL == request )
{
*value_int = 1;
diff --git a/src/libs/zbxsysinfo/common/net.h b/src/libs/zbxsysinfo/common/net.h
index 8de79d45..95a54b56 100644
--- a/src/libs/zbxsysinfo/common/net.h
+++ b/src/libs/zbxsysinfo/common/net.h
@@ -21,6 +21,8 @@
#include "sysinfo.h"
+extern char *CONFIG_SOURCE_IP;
+
int tcp_expect(const char *host, unsigned short port, const char *request, const char *expect, const char *sendtoclose, int *value_int);
int TCP_LISTEN(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result);
int CHECK_PORT(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result);
diff --git a/src/libs/zbxsysinfo/simple/ntp.c b/src/libs/zbxsysinfo/simple/ntp.c
index 55c227a8..f1e7c082 100644
--- a/src/libs/zbxsysinfo/simple/ntp.c
+++ b/src/libs/zbxsysinfo/simple/ntp.c
@@ -22,6 +22,7 @@
#include "comms.h"
#include "log.h"
#include "cfg.h"
+#include "ntp.h"
#define NTP_SCALE 4294967296.0 /* 2^32, of course! */
@@ -190,7 +191,7 @@ int check_ntp(char *host, unsigned short port, int *value_int)
*value_int = 0;
- if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 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);
diff --git a/src/libs/zbxsysinfo/simple/ntp.h b/src/libs/zbxsysinfo/simple/ntp.h
index 2805b36a..4d9b0ea2 100644
--- a/src/libs/zbxsysinfo/simple/ntp.h
+++ b/src/libs/zbxsysinfo/simple/ntp.h
@@ -19,6 +19,8 @@
#if !defined(SYSINFO_SYMPLE_NTP_H_INCLUDED)
+extern char *CONFIG_SOURCE_IP;
+
int check_ntp(char *host, unsigned short port, int *value_int);
#endif /* SYSINFO_SYMPLE_NTP_H_INCLUDED */
diff --git a/src/libs/zbxsysinfo/simple/simple.c b/src/libs/zbxsysinfo/simple/simple.c
index 03bb05f7..b29b8e6f 100644
--- a/src/libs/zbxsysinfo/simple/simple.c
+++ b/src/libs/zbxsysinfo/simple/simple.c
@@ -118,7 +118,7 @@ static int check_ssh(const char *host, unsigned short port, int *value_int)
assert(value_int);
*value_int = 0;
- if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0))) {
+ if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 0))) {
if( SUCCEED == (ret = zbx_tcp_recv(&s, &recv_buf)) )
{
if ( 0 == strncmp(recv_buf, "SSH", 3) )
diff --git a/src/libs/zbxsysinfo/simple/simple.h b/src/libs/zbxsysinfo/simple/simple.h
index cc00e2ce..41f47443 100644
--- a/src/libs/zbxsysinfo/simple/simple.h
+++ b/src/libs/zbxsysinfo/simple/simple.h
@@ -21,6 +21,7 @@
#include "sysinfo.h"
+extern char *CONFIG_SOURCE_IP;
extern ZBX_METRIC parameters_simple[];
int CHECK_SERVICE_PERF(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result);