summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsasha <sasha@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2007-09-17 09:35:13 +0000
committersasha <sasha@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2007-09-17 09:35:13 +0000
commit2ae95f35e566afdee93ea06bbf02443257ce7716 (patch)
tree0eddf35ca439ddc34473ffe97fce4615705017ad
parentcb2c5743fee519c1490317552b98a09f48daf92a (diff)
downloadzabbix-2ae95f35e566afdee93ea06bbf02443257ce7716.tar.gz
zabbix-2ae95f35e566afdee93ea06bbf02443257ce7716.tar.xz
zabbix-2ae95f35e566afdee93ea06bbf02443257ce7716.zip
[DEV-23] improvements in configure.in IPv6 (Sasha)
[DEV-23] Autodiscovery for IPv6 (Sasha) [DEV-17] Add support of IPv6 to standard library (comms.c) (Sasha) [DEV-21] extended size of IP fields to accept IPv6 style IPs (Alexei) [DEV-21] added basic validation of IPv6 IP addresses in GUI (Alexei) [DEV-18] Modified structures of include/db.h to have larger length for IP addresses. [DEV-18] database schema enhanced for IPv6 addresses (Alexei) Minor fix for confgure.in. support of --enable-ipv6 for configure.in (Alexei) git-svn-id: svn://svn.zabbix.com/trunk@4752 97f52cf1-0a1b-0410-bd0e-c28be96e8082
-rw-r--r--ChangeLog6
-rw-r--r--configure.in28
-rw-r--r--create/schema/schema.sql6
-rw-r--r--frontends/php/include/defines.inc.php2
-rw-r--r--frontends/php/include/forms.inc.php9
-rw-r--r--frontends/php/include/validate.inc.php89
-rwxr-xr-xgo2
-rw-r--r--include/comms.h3
-rw-r--r--include/db.h4
-rw-r--r--src/alphacode/poller/poller.c3
-rw-r--r--src/libs/zbxcommon/misc.c275
-rw-r--r--src/libs/zbxcomms/comms.c250
-rw-r--r--src/libs/zbxemail/email.c176
-rw-r--r--src/zabbix_server/discoverer/discoverer.c87
-rw-r--r--src/zabbix_server/operations.c36
-rw-r--r--src/zabbix_server/server.c128
16 files changed, 842 insertions, 262 deletions
diff --git a/ChangeLog b/ChangeLog
index 0152c911..ecbeaabc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,12 @@ Changes for 1.5:
Changes for 1.4.3:
+ - [DEV-23] Autodiscovery for IPv6 (Sasha)
+ - [DEV-17] Add support of IPv6 to standard library (comms.c) (Sasha)
+ - [DEV-21] extended size of IP fields to accept IPv6 style IPs (Alexei)
+ - [DEV-21] added basic validation of IPv6 IP addresses in GUI (Alexei)
+ - [DEV-18] database schema enhanced for IPv6 addresses (Alexei)
+ - [DEV-20] support of --enable-ipv6 for configure.in (Alexei)
- [NTT-16] added synchronisation of last value and timestamp for DM (Alexei)
- [ZBX-1] fixed wrong status of function "nodata" after server restart (Sasha)
- [ZBX-33] fixed problem in table names in data.sql for PostgreSQL (Sasha)
diff --git a/configure.in b/configure.in
index 42540c32..122676fb 100644
--- a/configure.in
+++ b/configure.in
@@ -547,11 +547,25 @@ esac],
[agent=no])
AM_CONDITIONAL(AGENT, test x$agent = xyes)
+AC_ARG_ENABLE(ipv6,[ --enable-ipv6 Turn on support of IPv6],
+[case "${enableval}" in
+ yes) ipv6=yes ;;
+ no) ipv6=no ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for --enable-ipv6]) ;;
+esac],
+[ipv6=no])
+
have_db="no"
have_odbc="no"
have_web_monitoring="no"
have_jabber="no"
have_snmp="no"
+have_ipv6="no"
+
+if test "$ipv6" = "yes"; then
+ AC_DEFINE(HAVE_IPV6,1,[Define to 1 if IPv6 should be enabled.])
+ have_ipv6="yes"
+fi
if test "$server" = "yes"; then
@@ -923,13 +937,13 @@ Configuration:
if test "x$server" != "xno"; then
-echo " With database: ${have_db}
- Enable DB monitor via: ${have_odbc}
- WEB Monitoring via: ${have_web_monitoring}
- Native Jabber: ${have_jabber}
- SNMP: ${have_snmp}
- Linker flags: ${LDFLAGS} ${SERVER_LDFLAGS}
- Libraries: ${LIBS} ${SERVER_LIBS}"
+echo " With database: ${have_db}
+ WEB Monitoring via: ${have_web_monitoring}
+ Native Jabber: ${have_jabber}
+ SNMP: ${have_snmp}
+ IPv6: ${have_ipv6}
+ Linker flags: ${LDFLAGS} ${SERVER_LDFLAGS}
+ Libraries: ${LIBS} ${SERVER_LIBS}"
fi
diff --git a/create/schema/schema.sql b/create/schema/schema.sql
index 26fd43e8..31da1288 100644
--- a/create/schema/schema.sql
+++ b/create/schema/schema.sql
@@ -53,7 +53,7 @@ FIELD |ports |t_varchar(255) |'0' |NOT NULL |ZBX_SYNC
TABLE|dhosts|dhostid|ZBX_SYNC
FIELD |dhostid |t_id |'0' |NOT NULL |ZBX_SYNC
FIELD |druleid |t_id |'0' |NOT NULL |ZBX_SYNC
-FIELD |ip |t_varchar(15) |'' |NOT NULL |ZBX_SYNC
+FIELD |ip |t_varchar(39) |'' |NOT NULL |ZBX_SYNC
FIELD |status |t_integer |'0' |NOT NULL |ZBX_SYNC
FIELD |lastup |t_integer |'0' |NOT NULL |ZBX_SYNC
FIELD |lastdown |t_integer |'0' |NOT NULL |ZBX_SYNC
@@ -122,7 +122,7 @@ TABLE|nodes|nodeid|
FIELD |nodeid |t_integer |'0' |NOT NULL |0
FIELD |name |t_varchar(64) |'0' |NOT NULL |0
FIELD |timezone |t_integer |'0' |NOT NULL |ZBX_SYNC
-FIELD |ip |t_varchar(15) |'' |NOT NULL |ZBX_SYNC
+FIELD |ip |t_varchar(39) |'' |NOT NULL |ZBX_SYNC
FIELD |port |t_integer |'10051'|NOT NULL |ZBX_SYNC
FIELD |slave_history |t_integer |'30' |NOT NULL |ZBX_SYNC
FIELD |slave_trends |t_integer |'365' |NOT NULL |ZBX_SYNC
@@ -381,7 +381,7 @@ FIELD |hostid |t_id |'0' |NOT NULL |ZBX_SYNC
FIELD |host |t_varchar(64) |'' |NOT NULL |ZBX_SYNC
FIELD |dns |t_varchar(64) |'' |NOT NULL |ZBX_SYNC
FIELD |useip |t_integer |'1' |NOT NULL |ZBX_SYNC
-FIELD |ip |t_varchar(15) |'127.0.0.1'|NOT NULL |ZBX_SYNC
+FIELD |ip |t_varchar(39) |'127.0.0.1'|NOT NULL |ZBX_SYNC
FIELD |port |t_integer |'10050'|NOT NULL |ZBX_SYNC
FIELD |status |t_integer |'0' |NOT NULL |ZBX_SYNC
FIELD |disable_until |t_integer |'0' |NOT NULL |0
diff --git a/frontends/php/include/defines.inc.php b/frontends/php/include/defines.inc.php
index d52df3c4..8360dd51 100644
--- a/frontends/php/include/defines.inc.php
+++ b/frontends/php/include/defines.inc.php
@@ -437,6 +437,8 @@
/* Define if your logs are in non-standard format */
/* define('ZBX_LOG_ENCODING_DEFAULT', 'Shift_JIS');*/
+ define('ZBX_HAVE_IPV6', 1);
+
global $_GET, $_POST, $_COOKIE, $_REQUEST;
/* Support for PHP5. PHP5 does not have $HTTP_..._VARS */
diff --git a/frontends/php/include/forms.inc.php b/frontends/php/include/forms.inc.php
index a92aafae..2589473e 100644
--- a/frontends/php/include/forms.inc.php
+++ b/frontends/php/include/forms.inc.php
@@ -4087,7 +4087,14 @@ include_once 'include/discovery.inc.php';
else
{
$frmHost->AddRow(S_DNS_NAME,new CTextBox("dns",$dns,"40"));
- $frmHost->AddRow(S_IP_ADDRESS,new CTextBox("ip",$ip,"15"));
+ if(defined('ZBX_HAVE_IPV6'))
+ {
+ $frmHost->AddRow(S_IP_ADDRESS,new CTextBox("ip",$ip,"39"));
+ }
+ else
+ {
+ $frmHost->AddRow(S_IP_ADDRESS,new CTextBox("ip",$ip,"15"));
+ }
$cmbConnectBy = new CComboBox('useip', $useip);
$cmbConnectBy->AddItem(0, S_DNS_NAME);
diff --git a/frontends/php/include/validate.inc.php b/frontends/php/include/validate.inc.php
index 997e7f76..a628744f 100644
--- a/frontends/php/include/validate.inc.php
+++ b/frontends/php/include/validate.inc.php
@@ -70,15 +70,41 @@
{
return 'ereg(\'^([0-9a-zA-Z\_\.[.-.]\$ ]+)$\',{'.$var.'})&&';
}
-
- function validate_ip($str,&$arr)
+ function validate_ipv4($str,&$arr)
{
if( !ereg('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$', $str, $arr) ) return false;
for($i=1; $i<=4; $i++) if( !is_numeric($arr[$i]) || $arr[$i] > 255 || $arr[$i] < 0 ) return false;
return true;
}
+ function validate_ipv6($str,&$arr)
+ {
+ $pattern1 = '([A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}';
+ $pattern2 = ':(:[A-Fa-f0-9]{1,4}){1,7}';
+ $pattern3 = '[A-Fa-f0-9]{1,4}::([A-Fa-f0-9]{1,4}:){0,5}[A-Fa-f0-9]{1,4}';
+ $pattern4 = '([A-Fa-f0-9]{1,4}:){2}:([A-Fa-f0-9]{1,4}:){0,4}[A-Fa-f0-9]{1,4}';
+ $pattern5 = '([A-Fa-f0-9]{1,4}:){3}:([A-Fa-f0-9]{1,4}:){0,3}[A-Fa-f0-9]{1,4}';
+ $pattern6 = '([A-Fa-f0-9]{1,4}:){4}:([A-Fa-f0-9]{1,4}:){0,2}[A-Fa-f0-9]{1,4}';
+ $pattern7 = '([A-Fa-f0-9]{1,4}:){5}:([A-Fa-f0-9]{1,4}:){0,1}[A-Fa-f0-9]{1,4}';
+ $pattern8 = '([A-Fa-f0-9]{1,4}:){6}:[A-Fa-f0-9]{1,4}';
+
+ $full = "/^($pattern1)$|^($pattern2)$|^($pattern3)$|^($pattern4)$|^($pattern5)$|^($pattern6)$|^($pattern7)$|^($pattern8)$/";
+
+ if( !ereg($full, $str, $arr) ) return false;
+ return true;
+ }
- function validate_ip_range($str)
+ function validate_ip($str,&$arr)
+ {
+ if(validate_ipv4($str,&$arr))
+ return true;
+ if(defined('ZBX_HAVE_IPV6'))
+ {
+ return validate_ipv6($str,&$arr);
+ }
+ return false;
+ }
+
+/* function validate_ip_range($str)
{
foreach(explode(',',$str) as $ip_range)
{
@@ -100,7 +126,64 @@
}
return true;
}
+*/
+ function validate_ip_range($str)
+ {
+ foreach(explode(',',$str) as $ip_range)
+ {
+ $parts = explode('-', $ip_range);
+ $parts_count = count($parts);
+ if($parts_count > 2) return false;
+
+ if(validate_ipv4($parts[0], $arr))
+ {
+ $ip_parts = explode('.', $parts[0]);
+
+ if( $parts_count == 2 )
+ {
+ if( !ereg('^[0-9]{1,3}$', $parts[1]) ) return false;
+
+ sscanf($ip_parts[3], "%d", $from_value);
+ sscanf($parts[1], "%d", $to_value);
+ if($to_value > 255 || $from_value > $to_value) return false;
+ }
+ }
+ else if( defined('ZBX_HAVE_IPV6') && validate_ipv6($parts[0], $arr) )
+ {
+ $ip_parts = explode(':', $parts[0]);
+ $ip_parts_count = count($ip_parts);
+
+ if( $parts_count == 2 )
+ {
+ if( !ereg('^[A-Fa-f0-9]{1,4}$', $parts[1]) ) return false;
+
+ sscanf($ip_parts[$ip_parts_count - 1], "%x", $from_value);
+ sscanf($parts[1], "%x", $to_value);
+ if($from_value > $to_value) return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+ return true;
+ }
+/* function validate_ip_range($str)
+ {
+ if(defined('ZBX_HAVE_IPV6'))
+ {
+ return validate_ipv4_ipv6_range($str);
+ }
+ else
+ {
+ return validate_ipv4_range($str);
+ }
+ return false;
+ }
+*/
function validate_port_list($str)
{
foreach(explode(',',$str) as $port_range)
diff --git a/go b/go
index ed64f3c2..0b1ebc29 100755
--- a/go
+++ b/go
@@ -33,7 +33,7 @@ cd -
#export CFLAGS="-Wall -pedantic"
#for db in sqlite3 pgsql mysql; do
for db in mysql; do
- ./configure --enable-agent --with-net-snmp --with-libcurl --with-ldap --enable-server --with-$db --prefix=`pwd` 2>>WARNINGS >/dev/null
+ ./configure --enable-agent --enable-server --with-jabber --with-ldap --with-libcurl --with-$db --with-net-snmp --prefix=`pwd` --enable-ipv6 2>>WARNINGS >/dev/null
echo Cleaning...
make clean 2>>WARNINGS >/dev/null
echo Making...
diff --git a/include/comms.h b/include/comms.h
index 50ecde1f..29fe4f69 100644
--- a/include/comms.h
+++ b/include/comms.h
@@ -32,6 +32,7 @@ typedef enum {
typedef int ZBX_SOCKET;
#endif /* SOCKET || _WINDOWS */
+
typedef struct sockaddr_in ZBX_SOCKADDR;
typedef enum
@@ -59,7 +60,7 @@ int zbx_tcp_error(void);
struct hostent *zbx_gethost(const char *hostname);
#if !defined(_WINDOWS)
-struct hostent *zbx_gethost_by_ip(const char *ip);
+void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen);
#endif /* WINDOWS */
void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o);
diff --git a/include/db.h b/include/db.h
index e2937c57..f8a371af 100644
--- a/include/db.h
+++ b/include/db.h
@@ -104,7 +104,7 @@ typedef enum {
#define MAX_HOST_HOST_LEN 64
#define MAX_ITEM_KEY_LEN 255
-#define MAX_ITEM_IP_LEN 15
+#define MAX_ITEM_IP_LEN 39
#define MAX_ITEM_SNMP_COMMUNITY_LEN 64
#define MAX_ITEM_SNMP_OID_LEN 255
@@ -127,7 +127,7 @@ typedef enum {
#define HOST_HOST_LEN_MAX HOST_HOST_LEN+1
#define HOST_DNS_LEN 64
#define HOST_DNS_LEN_MAX HOST_DNS_LEN+1
-#define HOST_IP_LEN 15
+#define HOST_IP_LEN 39
#define HOST_IP_LEN_MAX HOST_IP_LEN+1
#define HOST_ERROR_LEN 128
#define HOST_ERROR_LEN_MAX HOST_ERROR_LEN+1
diff --git a/src/alphacode/poller/poller.c b/src/alphacode/poller/poller.c
index ad24290f..b86f8e3c 100644
--- a/src/alphacode/poller/poller.c
+++ b/src/alphacode/poller/poller.c
@@ -170,14 +170,13 @@ int main()
for(i=0;i<NUM;i++)
{
- servaddr_in.sin_family=AF_INET;
if(NULL == (hp = zbx_gethost(ip)))
{
perror("gethost() failed");
}
+ 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);
s=socket(AF_INET,SOCK_STREAM,0);
diff --git a/src/libs/zbxcommon/misc.c b/src/libs/zbxcommon/misc.c
index d0178da4..9f004783 100644
--- a/src/libs/zbxcommon/misc.c
+++ b/src/libs/zbxcommon/misc.c
@@ -233,6 +233,203 @@ int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char
return i;
}
+#if defined(HAVE_IPV6)
+/******************************************************************************
+ * *
+ * Function: expand_ipv6 *
+ * *
+ * Purpose: convert short ipv6 addresses to expanded type *
+ * *
+ * Parameters: ip - IPv6 IPs [12fc::2] *
+ * buf - result value [12fc:0000:0000:0000:0000:0000:0000:0002] *
+ * *
+ * Return value: FAIL - invlid IP address, SUCCEED - conversion OK *
+ * *
+ * Author: Alksander Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+int expand_ipv6(const char *ip, char *str, size_t str_len )
+{
+ unsigned int i[8]; /* x:x:x:x:x:x:x:x */
+ char buf[5], *ptr;
+ int c, dc, pos = 0, j, len, ip_len, ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In expand_ipv6(ip:%s)", ip);
+
+ c = 0; /* colons count */
+ for(ptr = strchr(ip, ':'); ptr != NULL; ptr = strchr(ptr + 1, ':'))
+ {
+ c ++;
+ }
+
+ if(c < 2 || c > 7)
+ {
+ goto out;
+ }
+
+ ip_len = strlen(ip);
+ if((ip[0] == ':' && ip[1] != ':') || (ip[ip_len - 1] == ':' && ip[ip_len - 2] != ':'))
+ {
+ goto out;
+ }
+
+ memset(i, 0x00, sizeof(i));
+
+ dc = 0; /* double colon flag */
+ len = 0;
+ for(j = 0; j<ip_len; j++)
+ {
+ if((ip[j] >= '0' && ip[j] <= '9') || (ip[j] >= 'A' && ip[j] <= 'F') || (ip[j] >= 'a' && ip[j] <= 'f'))
+ {
+ if(len > 3)
+ {
+ goto out;
+ }
+ buf[len ++] = ip[j];
+ }
+ else if(ip[j] != ':')
+ {
+ goto out;
+ }
+
+ if(ip[j] == ':' || ip[j + 1] == '\0')
+ {
+ if(len)
+ {
+ buf[len] = 0x00;
+ sscanf(buf, "%x", &i[pos]);
+ pos ++;
+ len = 0;
+ }
+
+ if(ip[j + 1] == ':')
+ {
+ if(dc == 0)
+ {
+ dc = 1;
+ pos = ( 8 - c ) + pos + (j == 0 ? 1 : 0);
+ }
+ else
+ {
+ goto out;
+ }
+ }
+ }
+ }
+ zbx_snprintf(str, str_len, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]);
+ ret = SUCCEED;
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End expand_ipv6(ip:%s,str:%s,ret:%s)", ip, str, ret == SUCCEED ? "SUCCEED" : "FAIL");
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: ip_in_list_ipv6 *
+ * *
+ * Purpose: check if ip matches range of ip addresses *
+ * *
+ * Parameters: list - IPs [12fc::2-55,::45] *
+ * *
+ * Return value: FAIL - out of range, SUCCEED - within the range *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+int ip_in_list_ipv6(char *list, char *ip)
+{
+ char *start, *comma = NULL, *dash = NULL, buffer[MAX_STRING_LEN];
+ int i[8], j[9], ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In ip_in_list(list:%s,ip:%s)", list, ip);
+
+ if(FAIL == expand_ipv6(ip, buffer, sizeof(buffer)))
+ {
+ goto out;
+ }
+
+ if(sscanf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7]) != 8)
+ {
+ goto out;
+ }
+
+ for(start = list; start[0] != '\0';)
+ {
+
+ if(NULL != (comma = strchr(start, ',')))
+ {
+ comma[0] = '\0';
+ }
+
+ if(NULL != (dash = strchr(start, '-')))
+ {
+ dash[0] = '\0';
+ if(sscanf(dash + 1, "%x", &j[8]) != 1)
+ {
+ goto next;
+ }
+ }
+
+ if(FAIL == expand_ipv6(start, buffer, sizeof(buffer)))
+ {
+ goto next;
+ }
+
+ if(sscanf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", &j[0], &j[1], &j[2], &j[3], &j[4], &j[5], &j[6], &j[7]) != 8)
+ {
+ goto next;
+ }
+
+ if(dash == NULL)
+ {
+ j[8] = j[7];
+ }
+
+ if(i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] == j[3] &&
+ i[4] == j[4] && i[5] == j[5] && i[6] == j[6] &&
+ i[7] >= j[7] && i[7] <= j[8])
+ {
+ ret = SUCCEED;
+ break;
+ }
+next:
+ if(dash != NULL)
+ {
+ dash[0] = '-';
+ dash = NULL;
+ }
+
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ start = comma + 1;
+ comma = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+out:
+ if(dash != NULL)
+ {
+ dash[0] = '-';
+ }
+
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End ip_in_list(ret:%s)", ret == SUCCEED ? "SUCCEED" : "FAIL");
+ return ret;
+}
+#endif /*HAVE_IPV6*/
/******************************************************************************
* *
* Function: ip_in_list *
@@ -240,7 +437,6 @@ int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char
* Purpose: check if ip matches range of ip addresses *
* *
* Parameters: list - IPs [192.168.1.1-244,192.168.1.250] *
- * value- value *
* *
* Return value: FAIL - out of range, SUCCEED - within the range *
* *
@@ -252,49 +448,63 @@ int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char
int ip_in_list(char *list, char *ip)
{
char c = '\0';
- int i1,i2,i3,i4,i5,j1,j2,j3,j4;
+ int i[4], j[5];
int ret = FAIL;
- char *start = NULL, *end = NULL;
-
+ char *start = NULL, *comma = NULL, *dash = NULL;
- zabbix_log( LOG_LEVEL_DEBUG, "In ip_in_list(list:%s,ip:%s)",
- list,
- ip);
+ zabbix_log( LOG_LEVEL_DEBUG, "In ip_in_list(list:%s,ip:%s)", list, ip);
- if(sscanf(ip,"%d.%d.%d.%d",&j1,&j2,&j3,&j4) != 4)
- return FAIL;
+ if(sscanf(ip, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]) != 4)
+ {
+#if defined(HAVE_IPV6)
+ ret = ip_in_list_ipv6(list, ip);
+#endif /*HAVE_IPV6*/
+ goto out;
+ }
for(start = list; start[0] != '\0';)
{
- end=strchr(start, ',');
-
- if(end != NULL)
+ if(NULL != (comma = strchr(start, ',')))
{
- c=end[0];
- end[0]='\0';
+ comma[0] = '\0';
}
- if(sscanf(start,"%d.%d.%d.%d-%d",&i1,&i2,&i3,&i4,&i5) == 5)
+ if(NULL != (dash = strchr(start, '-')))
{
- if(i1==j1 && i2==j2 && i3==j3 && j4>=i4 && j4<=i5)
+ dash[0] = '\0';
+ if(sscanf(dash + 1, "%d", &j[4]) != 1)
{
- ret = SUCCEED;
- break;
+ goto next;
}
}
- else if(sscanf(start,"%d.%d.%d.%d",&i1,&i2,&i3,&i4) == 4)
+
+ if(sscanf(start, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) != 4)
{
- if(i1==j1 && i2==j2 && i3==j3 && j4==i4)
- {
- ret = SUCCEED;
- break;
- }
+ goto next;
}
- if(end != NULL)
+ if(dash == NULL)
{
- end[0]=c;
- start=end+1;
+ j[4] = j[3];
+ }
+
+ if(i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] >= j[3] && i[3] <= j[4])
+ {
+ ret = SUCCEED;
+ break;
+ }
+next:
+ if(dash != NULL)
+ {
+ dash[0] = '-';
+ dash = NULL;
+ }
+
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ start = comma + 1;
+ comma = NULL;
}
else
{
@@ -302,13 +512,18 @@ int ip_in_list(char *list, char *ip)
}
}
- if(end != NULL)
+out:
+ if(dash != NULL)
{
- end[0]=c;
+ dash[0] = '-';
}
- zabbix_log( LOG_LEVEL_DEBUG, "End ip_in_list(ret:%s)", ret == SUCCEED?"SUCCEED":"FAIL");
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ }
+ zabbix_log( LOG_LEVEL_DEBUG, "End ip_in_list(ret:%s)", ret == SUCCEED ? "SUCCEED" : "FAIL");
return ret;
}
diff --git a/src/libs/zbxcomms/comms.c b/src/libs/zbxcomms/comms.c
index e1f9f075..534fe010 100644
--- a/src/libs/zbxcomms/comms.c
+++ b/src/libs/zbxcomms/comms.c
@@ -112,28 +112,59 @@ static void __zbx_zbx_set_tcp_strerror(const char *fmt, ...)
* *
* Parameters: *
* *
- * Return value: hostent or NULL - an error occured *
+ * Return value: *
* *
* Author: Alexei Vladishev *
* *
* Comments: *
* *
******************************************************************************/
-struct hostent *zbx_gethost_by_ip(const char *ip)
+
+#if defined(HAVE_IPV6)
+void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen)
+{
+ struct addrinfo hints, *ai = NULL;
+
+ assert(ip);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ if(0 != getaddrinfo(ip, NULL, &hints, &ai))
+ {
+ host[0] = '\0';
+ goto out;
+ }
+ if(0 != getnameinfo(ai->ai_addr, ai->ai_addrlen, host, hostlen, NULL, 0, NI_NAMEREQD))
+ {
+ host[0] = '\0';
+ goto out;
+ }
+out:
+ freeaddrinfo(ai);
+}
+#else
+void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen)
{
struct in_addr addr;
- struct hostent* host;
+ struct hostent *hst;
assert(ip);
- if(inet_aton(ip, &addr) != 0)
+ if(inet_aton(ip, &addr) == 0)
{
- host = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
- if(host) return host;
+ host[0] = '\0';
+ return;
}
- return (struct hostent*) NULL;
+ if(NULL == (hst = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)))
+ {
+ host[0] = '\0';
+ return;
+ }
+
+ zbx_strlcpy(host, hst->h_name, hostlen);
}
+#endif /*HAVE_IPV6*/
#endif /* WINDOWS */
/******************************************************************************
@@ -232,7 +263,7 @@ static int zbx_tcp_start(void)
* *
* Parameters: *
* *
- * Return value: *
+ * Return value: *
* *
* Author: Alexei Vladishev *
* *
@@ -254,7 +285,7 @@ static void zbx_tcp_clean(zbx_sock_t *s)
* *
* Parameters: *
* *
- * Return value: *
+ * Return value: *
* *
* Author: Eugene Grigorjev *
* *
@@ -275,7 +306,7 @@ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o)
* *
* Parameters: *
* *
- * Return value: sockfd - open socket *
+ * Return value: sockfd - open socket *
* FAIL - an error occured *
* *
* Author: Alexei Vladishev *
@@ -283,9 +314,48 @@ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o)
* Comments: *
* *
******************************************************************************/
-int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
+#if defined(HAVE_IPV6)
+int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
+{
+ int ret=SUCCEED;
+ struct addrinfo *ai, hints;
+ 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_flags = AI_ADDRCONFIG;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if( 0 != getaddrinfo (ip, service, &hints, &ai)) {
+ zbx_set_tcp_strerror("Cannot resolve [%s]", ip);
+ ret=FAIL;
+ 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()));
+ ret=FAIL;
+ goto out;
+ }
+
+ 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);
+ ret=FAIL;
+ goto out;
+ }
+out:
+ freeaddrinfo (ai);
+ return ret;
+}
+#else
+int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
{
- ZBX_SOCKADDR myaddr_in;
ZBX_SOCKADDR servaddr_in;
struct hostent *hp;
@@ -299,7 +369,6 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
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);
@@ -310,10 +379,6 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
return FAIL;
}
- myaddr_in.sin_family = AF_INET;
- myaddr_in.sin_port = 0;
- myaddr_in.sin_addr.s_addr = INADDR_ANY;
-
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()));
@@ -323,7 +388,7 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
return SUCCEED;
}
-
+#endif /*HAVE_IPV6*/
/******************************************************************************
* *
* Function: zbx_tcp_send *
@@ -332,7 +397,7 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
* *
* Parameters: *
* *
- * Return value: SUCCEED - success *
+ * Return value: SUCCEED - success *
* FAIL - an error occured *
* *
* Author: Eugene Grigorjev *
@@ -420,7 +485,7 @@ void zbx_tcp_close(zbx_sock_t *s)
* *
* Parameters: *
* *
- * Return value: SUCCEED - success *
+ * Return value: SUCCEED - success *
* FAIL - an error occured *
* *
* Author: Alexei Vladishev *
@@ -434,17 +499,35 @@ int zbx_tcp_listen(
unsigned short listen_port
)
{
- ZBX_SOCKADDR serv_addr;
- int on;
+#if defined(HAVE_IPV6)
+ struct addrinfo hints, *ai = NULL;
+ char port[MAX_STRING_LEN];
+#else
+ ZBX_SOCKADDR serv_addr;
+#endif /*HAVE_IPV6*/
+ int on, res = FAIL, e;
ZBX_TCP_START();
zbx_tcp_clean(s);
- if( ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)) )
+#if defined(HAVE_IPV6)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+ 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 create socket [%s:%u] [%s]", listen_ip, listen_port ,strerror_from_system(zbx_sock_last_error()));
- return FAIL;
+ zbx_set_tcp_strerror("Cannot getaddrinfo [%s:%u] [%s]", listen_ip, listen_port, gai_strerror(e));
+ goto out;
+ }
+ if(ZBX_SOCK_ERROR == (s->socket = socket(ai->ai_family, ai->ai_socktype,0)))
+#else
+ if(ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)))
+#endif /*HAVE_IPV6*/
+ {
+ 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 */
@@ -457,29 +540,38 @@ int zbx_tcp_listen(
}
/* Create socket Fill in local address structure */
+#if defined(HAVE_IPV6)
+ if( -1 == bind(s->socket, ai->ai_addr, ai->ai_addrlen))
+#else
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);
+ 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)) )
+#endif /*HAVE_IPV6*/
{
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()));
- return FAIL;
+ goto out;
}
if( ZBX_SOCK_ERROR == listen(s->socket, SOMAXCONN) )
{
zbx_set_tcp_strerror("Listen failed. [%s]", strerror_from_system(zbx_sock_last_error()));
- return FAIL;
+ goto out;
}
- return SUCCEED;
+ res = SUCCEED;
+out:
+#if defined(HAVE_IPV6)
+ freeaddrinfo (ai);
+#endif /*HAVE_IPV6*/
+ return res;
}
/******************************************************************************
@@ -578,7 +670,7 @@ void zbx_tcp_free(zbx_sock_t *s)
* *
* Parameters: *
* *
- * Return value: SUCCEED - success *
+ * Return value: SUCCEED - success *
* FAIL - an error occured *
* *
* Author: Eugene Grigorjev *
@@ -722,16 +814,21 @@ int zbx_tcp_check_security(
int allow_if_empty
)
{
- ZBX_SOCKADDR name;
+#if defined(HAVE_IPV6)
+ struct sockaddr_storage name;
+ struct addrinfo hints, *ai = NULL;
+#else
+ ZBX_SOCKADDR name;
+ struct hostent *hp;
+ char *sip;
+#endif
socklen_t nlen;
- struct hostent *hp;
-
- char
- tmp[MAX_STRING_LEN],
+ char tmp[MAX_STRING_LEN],
sname[MAX_STRING_LEN],
- *sip,
- *host;
+ *start = NULL,
+ *end = NULL,
+ c = '\0';
zabbix_log( LOG_LEVEL_DEBUG, "In check_security()");
@@ -739,7 +836,11 @@ int zbx_tcp_check_security(
{
return SUCCEED;
}
+#if defined(HAVE_IPV6)
+ nlen = sizeof(struct sockaddr_storage);
+#else
nlen = sizeof(ZBX_SOCKADDR);
+#endif /*HAVE_IPV6*/
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()));
@@ -747,27 +848,86 @@ int zbx_tcp_check_security(
}
else
{
+#if !defined(HAVE_IPV6)
strcpy(sname, inet_ntoa(name.sin_addr));
-
+#endif /*HAVE_IPV6*/
strscpy(tmp,ip_list);
- host = (char *)strtok(tmp,",");
-
- while( NULL != host )
+ 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( 0 != (hp = zbx_gethost(host)))
+#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( 0 == strcmp(sname, sip))
{
- return SUCCEED;
+ return SUCCEED;
}
}
- host = (char *)strtok(NULL,",");
+#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;
}
-
diff --git a/src/libs/zbxemail/email.c b/src/libs/zbxemail/email.c
index b89b9cac..f507ea1b 100644
--- a/src/libs/zbxemail/email.c
+++ b/src/libs/zbxemail/email.c
@@ -46,111 +46,81 @@
*/
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 s;
- int i,e;
- char c[MAX_STRING_LEN], *cp = NULL;
- struct hostent *hp;
+ 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 str_time[MAX_STRING_LEN];
+ struct tm *local_time = NULL;
+ time_t email_time;
- struct sockaddr_in myaddr_in;
- struct sockaddr_in servaddr_in;
+ char *OK_220="220";
+ char *OK_250="250";
+ char *OK_251="251";
+ char *OK_354="354";
- 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);
- zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]",
- smtp_server);
-
- servaddr_in.sin_family=AF_INET;
-
- if(NULL == (hp = zbx_gethost(smtp_server)))
- {
- zbx_snprintf(error,max_error_len,"Cannot get IP for mailserver [%s]",smtp_server);
- zabbix_log(LOG_LEVEL_DEBUG, "%s",error);
- zabbix_syslog("%s",error);
- return FAIL;
- }
-
- servaddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
- servaddr_in.sin_port=htons(25);
-
- s=socket(AF_INET,SOCK_STREAM,0);
- if(s == -1)
- {
- zbx_snprintf(error,max_error_len,"Cannot create socket [%s]",strerror(errno));
- zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
- zabbix_syslog("%s", error);
- return FAIL;
- }
-
- myaddr_in.sin_family = AF_INET;
- myaddr_in.sin_port=0;
- myaddr_in.sin_addr.s_addr=INADDR_ANY;
-
- if( connect(s,(struct sockaddr *)&servaddr_in,sizeof(struct sockaddr_in)) == -1 )
+ if(FAIL == zbx_tcp_connect(&s, smtp_server, 25))
{
- zbx_snprintf(error,max_error_len,"Cannot connect to SMTP server [%s] [%s]", smtp_server, strerror(errno));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,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);
- close(s);
- return FAIL;
+ 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);
- close(s);
- return FAIL;
+ 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,c,strlen(c));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,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);
- close(s);
- return FAIL;
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
}
@@ -158,55 +128,55 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
zbx_snprintf(c,sizeof(c),"MAIL FROM: <%s>\r\n",smtp_email);
- e=write(s,c,strlen(c));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,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);
- close(s);
- return FAIL;
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"RCPT TO: <%s>\r\n",mailto);
- e=write(s,c,strlen(c));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,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);
- close(s);
- return FAIL;
+ 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)
@@ -214,38 +184,38 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
zbx_snprintf(error,max_error_len,"Wrong answer on RCPT TO [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"DATA\r\n");
- e=write(s,c,strlen(c));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,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);
- close(s);
- return FAIL;
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
cp = string_replace(mailsubject, "\r\n", "\n");
@@ -261,7 +231,7 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
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,cp,strlen(cp));
+ e=write(s.socket,cp,strlen(cp));
zbx_free(cp);
zbx_free(mailsubject);
zbx_free(mailbody);
@@ -270,54 +240,52 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"\r\n.\r\n");
- e=write(s,c,strlen(c));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
- zabbix_log(LOG_LEVEL_DEBUG, "Error receivng answer on . request [%s]", strerror(errno));
- zabbix_syslog("Error receivng answer on . request [%s]", strerror(errno));
zbx_snprintf(error,max_error_len,"Error receivng answer on . request [%s]", strerror(errno));
- close(s);
- return FAIL;
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"QUIT\r\n");
- e=write(s,c,strlen(c));
+ 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);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
-
- close(s);
-
-
- return SUCCEED;
+out:
+ zbx_tcp_close(&s);
+ return ret;
}
diff --git a/src/zabbix_server/discoverer/discoverer.c b/src/zabbix_server/discoverer/discoverer.c
index bbbe876b..52e5ad36 100644
--- a/src/zabbix_server/discoverer/discoverer.c
+++ b/src/zabbix_server/discoverer/discoverer.c
@@ -710,12 +710,13 @@ static void process_rule(DB_DRULE *rule)
DB_ROW row;
DB_DCHECK check;
- char ip[MAX_STRING_LEN];
- int i1,i2,i3,i4,i5;
- int first, last, i;
+ char ip[MAX_STRING_LEN], prefix[MAX_STRING_LEN];
+ unsigned int j[9], i;
+ int first, last, ipv6;
char *curr_range = NULL,
- *next_range = NULL;
+ *next_range = NULL,
+ *dash = NULL, *colon;
assert(rule);
@@ -725,26 +726,78 @@ static void process_rule(DB_DRULE *rule)
for ( curr_range = rule->iprange; curr_range; curr_range = next_range )
{ /* split by ',' */
- if ( (next_range = strchr(curr_range, ',')) )
+ if ( NULL != (next_range = strchr(curr_range, ',')) )
{
- *next_range = '\0';
+ next_range[0] = '\0';
+ }
+
+ if ( NULL != (dash = strchr(curr_range, '-')) )
+ {
+ dash[0] = '\0';
}
first = last = -1;
- if ( sscanf(curr_range, "%d.%d.%d.%d-%d", &i1, &i2, &i3, &i4, &i5) == 5 )
+#if defined(HAVE_IPV6)
+ if ( SUCCEED == expand_ipv6(curr_range, ip, sizeof(ip)) )
{
- first = i4;
- last = i5;
+ ipv6 = 1;
+ if( sscanf(ip, "%x:%x:%x:%x:%x:%x:%x:%x", &j[0], &j[1], &j[2], &j[3], &j[4], &j[5], &j[6], &j[7]) == 8 )
+ {
+ first = j[7];
+
+ zbx_strlcpy( prefix, curr_range, sizeof(prefix) );
+ if( NULL != (colon = strrchr(prefix, ':')) )
+ {
+ ( colon + 1 )[0] = '\0';
+ }
+ }
+
+ if( dash != NULL )
+ {
+ if( sscanf(dash + 1, "%x", &j[8]) == 1 )
+ {
+ last = j[8];
+ }
+ }
+ else
+ {
+ last = first;
+ }
}
- else if( sscanf(curr_range, "%d.%d.%d.%d", &i1, &i2, &i3, &i4) == 4 )
+ else
{
- first = last = i4;
+#endif /* HAVE_IPV6 */
+ ipv6 = 0;
+ if( sscanf(curr_range, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) == 4 )
+ {
+ first = j[3];
+ }
+
+ if( dash != NULL )
+ {
+ if( sscanf(dash + 1, "%d", &j[4]) == 1 )
+ {
+ last = j[4];
+ }
+ }
+ else
+ {
+ last = first;
+ }
+#if defined(HAVE_IPV6)
+ }
+#endif /* HAVE_IPV6 */
+
+ if( dash )
+ {
+ dash[0] = '-';
+ dash = NULL;
}
if ( next_range )
{
- *next_range = ',';
- next_range++;
+ next_range[0] = ',';
+ next_range ++;
}
if( first < 0 || last < 0 )
@@ -756,9 +809,13 @@ static void process_rule(DB_DRULE *rule)
for ( i = first; i <= last; i++ )
{
- zbx_snprintf(ip, sizeof(ip), "%d.%d.%d.%d", i1, i2, i3, i);
+ switch( ipv6 )
+ {
+ case 0 : zbx_snprintf(ip, sizeof(ip), "%d.%d.%d.%d", j[0], j[1], j[2], i); break;
+ case 1 : zbx_snprintf(ip, sizeof(ip), "%s%x", prefix, i); break;
+ }
- zabbix_log(LOG_LEVEL_DEBUG, "IP [%s]", ip);
+ zabbix_log(LOG_LEVEL_DEBUG, "Discovery: process_rule() [first %d] [last %d] [IP %s]", prefix, first, last, ip);
result = DBselect("select dcheckid,druleid,type,key_,snmp_community,ports from dchecks where druleid=" ZBX_FS_UI64,
rule->druleid);
diff --git a/src/zabbix_server/operations.c b/src/zabbix_server/operations.c
index c45d65a4..c90c57ba 100644
--- a/src/zabbix_server/operations.c
+++ b/src/zabbix_server/operations.c
@@ -461,8 +461,7 @@ static zbx_uint64_t add_discovered_host(zbx_uint64_t dhostid)
DB_ROW row2;
zbx_uint64_t hostid = 0;
char *ip;
- struct hostent* host;
- char host_esc[MAX_STRING_LEN];
+ char host[MAXDNAME], host_esc[MAX_STRING_LEN];
zabbix_log(LOG_LEVEL_DEBUG, "In add_discovered_host(dhostid:" ZBX_FS_UI64 ")",
dhostid);
@@ -475,17 +474,10 @@ static zbx_uint64_t add_discovered_host(zbx_uint64_t dhostid)
ip=row[0];
alarm(CONFIG_TIMEOUT);
- host = zbx_gethost_by_ip(ip);
+ zbx_gethost_by_ip(ip, host, sizeof(host));
alarm(0);
- if(host != NULL)
- {
- DBescape_string(host->h_name, host_esc, sizeof(host_esc));
- }
- else
- {
- host_esc[0]='\0';
- }
+ DBescape_string(host, host_esc, sizeof(host_esc));
result2 = DBselect("select hostid from hosts where ip='%s' and " ZBX_COND_NODEID,
ip,
@@ -494,23 +486,11 @@ static zbx_uint64_t add_discovered_host(zbx_uint64_t dhostid)
if(!row2 || DBis_null(row2[0]) == SUCCEED)
{
hostid = DBget_maxid("hosts","hostid");
- /* Use host name if exists, IP otherwise */
- if(host_esc[0] != '\0')
- {
- DBexecute("insert into hosts (hostid,host,useip,ip,dns) values (" ZBX_FS_UI64 ",'%s',1,'%s','%s')",
- hostid,
- host_esc,
- ip,
- host_esc);
- }
- else
- {
- DBexecute("insert into hosts (hostid,host,useip,ip,dns) values (" ZBX_FS_UI64 ",'%s',1,'%s','%s')",
- hostid,
- ip,
- ip,
- host_esc);
- }
+ DBexecute("insert into hosts (hostid,host,useip,ip,dns) values (" ZBX_FS_UI64 ",'%s',1,'%s','%s')",
+ hostid,
+ (host[0] != '\0' ? host_esc : ip), /* Use host name if exists, IP otherwise */
+ ip,
+ host_esc);
}
else
{
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index ccbf9ecd..cf3f3150 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -16,9 +16,9 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
-
-/*#define ZABBIX_TEST*/
-
+/*
+#define ZABBIX_TEST
+*/
#include "common.h"
#include "cfg.h"
@@ -498,14 +498,13 @@ void test_variable_argument_list(void)
void test_zbx_gethost(void)
{
- struct hostent* host;
+/* struct hostent* host;
char hostname[]="194.8.11.69";
-/* char hostname[]="gobbo.caves.lv";*/
host = zbx_gethost_by_ip(hostname);
- printf("Host1 [%s]\n", host->h_name);
+ printf("Host1 [%s]\n", host->h_name);*/
}
void test_templates()
@@ -564,16 +563,17 @@ ZBX_TEST_TIME expressions[]=
printf("Passed OK\n");
}
*/
-/*
+
void test_email()
{
- char str_error[0xFF];
+ char str_error[MAX_STRING_LEN];
+ alarm(5);
if ( FAIL == send_email(
- "test.com",
- "test.com",
- "test@test.com",
- "test@test.com",
+ "mail.apollo.lv",
+ "zabbix.com",
+ "sasha@zabbix.com",
+ "aleksander.vladishev@zabbix.com",
"This is a TEST message",
"Big message\r\n"
" 1 Line\n"
@@ -601,10 +601,10 @@ void test_email()
printf("ERROR: %s\n", str_error);
else
printf("OK\n");
-
+ alarm(0);
}
-*/
+
/*
void test_extract_numbers(void)
@@ -649,6 +649,66 @@ void test_trigger_description()
}
*/
+void test_zbx_tcp_connect(void)
+{
+#define ZBX_TEST_TCP_CONNECT struct zbx_test_tcp_connect_t
+ZBX_TEST_TCP_CONNECT
+{
+ char *hostname;
+ unsigned short port;
+};
+
+ZBX_TEST_TCP_CONNECT expressions[]=
+{
+ {"127.0.0.1", 80},
+ {"support.zabbix.com", 8080},/*81.198.122.245*/
+ {"www.iscentrs.lv", 80},/*81.198.60.94*/
+ {"81.171.84.52", 80},
+ {"64.233.183.103", 80},/*nf-in-f103.google.com*/
+ {"::1", 80},
+ {"::1", 22},
+ {"12fc::5", 80},
+ {"192.168.3.5", 80},
+ {NULL}
+};
+
+ int i;
+ zbx_sock_t s;
+ char host[MAXDNAME];
+ char ip_list[] = "81.171.84.52,nf-in-f103.google.com,ip6-localhost,localhost";
+
+ for(i = 0; expressions[i].hostname != NULL; i ++)
+ {
+ zbx_gethost_by_ip(expressions[i].hostname, host, sizeof(host));
+ printf("[%25s]:%-5d %-30s ", expressions[i].hostname, expressions[i].port, host);
+
+ alarm(5);
+ switch(zbx_tcp_connect(&s, expressions[i].hostname, expressions[i].port))
+ {
+ case SUCCEED :
+ printf("Succeed");
+
+ if(FAIL == zbx_tcp_check_security(&s, ip_list, 0))
+ {
+ printf(" \n%s", zbx_tcp_strerror());
+ }
+ zbx_tcp_close(&s);
+ break;
+ case FAIL :
+ printf("Fail %s\n", zbx_tcp_strerror());
+ break;
+ }
+ alarm(0);
+ printf("\n");
+ }
+}
+/*
+static void test_child_signal_handler(int sig)
+{
+ printf( "sdfsdfsdfsf" );
+}
+*/
+
void test_ip_in_list()
{
#define ZBX_TEST_IP struct zbx_test_ip_t
@@ -661,12 +721,21 @@ ZBX_TEST_IP
ZBX_TEST_IP expressions[]=
{
- {"10.0.0.1-255", "10.0.0.30", SUCCEED},
+ {"10.0.0.1-29", "10.0.0.30", FAIL},
{"192.168.0.1-255,192.168.1.1-255", "192.168.2.201", FAIL},
- {"172.16.0.0,172.16.0.1,172.16.0.2-200,172.16.0.201", "172.16.0.201", SUCCEED},
- {"172.31.255.1-255", "172.31.255.43", SUCCEED},
+ {"172.16.0.0,172.16.0.1,172.16.0.2,172.16.0.44-250", "172.16.0.201", SUCCEED},
+ {"172.31.255.43-55", "172.31.255.47", SUCCEED},
{"86.57.15.94", "86.57.15.95", FAIL},
{"86.57.15.94", "86.57.15.94", SUCCEED},
+#if defined(HAVE_IPV6)
+ {"2312:333::32-64,12fc::1-fffc", "12fc::ffff", FAIL},
+ {"2312:333::32-64,12fc::1-fffc", "2312:333::44", SUCCEED},
+ {"::a:b:a,::a:b:b,::a:b:c-e", "::a:b:f", FAIL},
+ {"192.168.200.1,::a:b:a,::a:b:b,::a:b:c-e,10.0.0.2", "::a:b:d", SUCCEED},
+ {"192.168.200.1,::a:b:a,::a:b:b,::a:b:c-e,10.0.0.2", "10.0.0.2", SUCCEED},
+ {"192.168.200.1,::a:b:a,::a:b:b,::a:b:c-,10.0.0.2", "::a:b:d", FAIL},
+ {"a:b:c::-f", "a:b:c::3", SUCCEED},
+#endif /*HAVE_IPV6*/
{NULL}
};
int i;
@@ -680,11 +749,11 @@ ZBX_TEST_IP expressions[]=
strcpy(list, expressions[i].list);
result = ip_in_list(list, expressions[i].ip);
- printf("list [%s] ip [%s] expected [%d] got [%d]\n",
+ printf("list [%50s] ip [%20s] expected [%7s] got [%7s]\n",
expressions[i].list,
expressions[i].ip,
- expressions[i].result,
- result);
+ expressions[i].result == SUCCEED ? "SUCCEED" : "FAIL",
+ result == SUCCEED ? "SUCCEED" : "FAIL");
if(expressions[i].result!=result)
{
printf("FAILED!\n");
@@ -721,6 +790,7 @@ void test()
/* test_email(); */
/* test_extract_numbers(); */
/* test_trigger_description(); */
+/* test_zbx_tcp_connect( );*/
test_ip_in_list();
printf("\n-= Test completed =-\n");
@@ -802,6 +872,18 @@ int main(int argc, char **argv)
}
#ifdef ZABBIX_TEST
+/* struct sigaction phan;
+
+ phan.sa_handler = test_child_signal_handler;
+ sigemptyset(&phan.sa_mask);
+ phan.sa_flags = 0;
+
+ sigaction(SIGINT, &phan, NULL);
+ sigaction(SIGQUIT, &phan, NULL);
+ sigaction(SIGTERM, &phan, NULL);
+ sigaction(SIGPIPE, &phan, NULL);
+ sigaction(SIGCHLD, &phan, NULL);
+*/
test();
zbx_on_exit();
@@ -852,6 +934,11 @@ int MAIN_ZABBIX_ENTRY(void)
#else
# define ODBC_FEATURE_STATUS " NO"
#endif
+#ifdef HAVE_IPV6
+# define IPV6_FEATURE_STATUS "YES"
+#else
+# define IPV6_FEATURE_STATUS " NO"
+#endif
/* zabbix_log( LOG_LEVEL_WARNING, "INFO [%s]", ZBX_SQL_MOD(a,%d)); */
zabbix_log( LOG_LEVEL_WARNING, "Starting zabbix_server. ZABBIX %s.", ZABBIX_VERSION);
@@ -861,6 +948,7 @@ int MAIN_ZABBIX_ENTRY(void)
zabbix_log( LOG_LEVEL_WARNING, "WEB monitoring: " LIBCURL_FEATURE_STATUS );
zabbix_log( LOG_LEVEL_WARNING, "Jabber notifications: " JABBER_FEATURE_STATUS );
zabbix_log( LOG_LEVEL_WARNING, "ODBC: " ODBC_FEATURE_STATUS );
+ zabbix_log( LOG_LEVEL_WARNING, "IPv6 support: " IPV6_FEATURE_STATUS );
zabbix_log( LOG_LEVEL_WARNING, "**************************");
DBconnect(ZBX_DB_CONNECT_EXIT);