Пример #1
0
/**
 * Advance the BDD iterator, taking into account that some assignments
 * need to be expanded twice.
 */
static void
advance_assignment(struct ipset_iterator *iterator)
{
    /* Check the current state of the iterator to determine how to
     * advance. */

    /* In most cases, the assignment we just finished only needed to be
     * expanded once.  So we move on to the next assignment and process
     * it. */
    if (CORK_LIKELY(iterator->multiple_expansion_state ==
                    IPSET_ITERATOR_NORMAL))
    {
        ipset_bdd_iterator_advance(iterator->bdd_iterator);
        process_assignment(iterator);
        return;
    }

    /* If the assignment needs to be expanded twice, we'll do the IPv4
     * expansion first.  If that's what we've just finished, do the IPv6
     * expansion next. */

    if (iterator->multiple_expansion_state == IPSET_ITERATOR_MULTIPLE_IPV4) {
        DEBUG("Expanding IPv6 second");

        iterator->multiple_expansion_state = IPSET_ITERATOR_MULTIPLE_IPV6;
        ipset_assignment_set
            (iterator->bdd_iterator->assignment, 0, IPSET_FALSE);
        expand_ipv6(iterator);
        return;
    }

    /* If we've just finished the IPv6 expansion, then we've finished
     * with this assignment.  Before moving on to the next one, we have
     * to reset variable 0 to EITHER (which it was before we started
     * this whole mess). */

    if (iterator->multiple_expansion_state == IPSET_ITERATOR_MULTIPLE_IPV6) {
        DEBUG("Finished both expansions");

        ipset_assignment_set
            (iterator->bdd_iterator->assignment, 0, IPSET_EITHER);
        ipset_bdd_iterator_advance(iterator->bdd_iterator);
        process_assignment(iterator);
        return;
    }
}
Пример #2
0
int
cloakhost(char *host, char *dest)
{
    char virt[HOSTLEN + 1], ip6buffer[INET6_ADDRSTRLEN], *p;
    unsigned int dotCount, colCount;
    int32_t csum;
    host_type_t htype;

    htype = host_type(host, &dotCount, &colCount);
    memset(virt, 0x0, HOSTLEN+1);

    switch (htype)
    {
	case HT_INVALID:
	    return 0;
	case HT_FQDN:
	    csum = fnv_hash(sha1_hash(host, strlen(host)), SHABUFLEN);

	    if (dotCount == 1)
	    {
		snprintf(virt, HOSTLEN, "%s%c%X.%s",
			 cloak_host,
			 (csum < 0 ? '=' : '-'),
			 (csum < 0 ? -csum : csum), host);
	    }
	    else if (dotCount > 1)
	    {
		int chlen = strlen(cloak_host) + 10; /* -12345678. */

		p = (char *) strchr((char *)host, '.');

		while((strlen(p) + chlen) > HOSTLEN)
		{
		    /* controllare i return value non sarebbe una cattiva idea... */
		    if ((p = (char *) strchr((char *) ++p, '.')) == NULL)
			return 0;
		}
		snprintf(virt, HOSTLEN, "%s%c%X.%s",
			 cloak_host,
			 (csum < 0 ? '=' : '-'),
			 (csum < 0 ? -csum : csum), p + 1);
	    }
	    else
		return 0;
	break;

	case HT_IPv4:
	{
	    char ipmask[16];

	    csum = fnv_hash(sha1_hash(host, strlen(host)), SHABUFLEN);

	    strncpy(ipmask, host, sizeof(ipmask));
	    ipmask[sizeof(ipmask) - 1] = '\0';
	    if ((p = strchr(ipmask, '.')) != NULL)
		if ((p = strchr(p + 1, '.')) != NULL)
		    *p = '\0';

	    if (p == NULL)
		snprintf(virt, HOSTLEN, "%s%c%X",
			 cloak_host, csum < 0 ? '=' : '-',
			 csum < 0 ? -csum : csum);
	    else
		snprintf(virt, HOSTLEN, "%s.%s%c%X",
			 ipmask, cloak_host, csum < 0 ? '=' : '-',
			 csum < 0 ? -csum : csum);
	    break;
	}

	case HT_IPv6:
	{
	    /* FFFFFFFUUUUUUUU */
	    int rv;
	    struct in6_addr ip6addr;

	    /* Expand address before hashing */
	    expand_ipv6(host, colCount, ip6buffer);
	    Debug((DEBUG_INFO, "%s expanded to %s (%u columns)", host, ip6buffer, colCount));
	    csum = fnv_hash(sha1_hash(ip6buffer, strlen(ip6buffer)), SHABUFLEN);

	    /* Clear the buffer */
	    memset(ip6buffer, 0, sizeof(ip6buffer));
	    /* Get raw bytes... */
	    rv = inet_pton(AF_INET6, host, &ip6addr);
	    if (rv <= 0)
	    {
		Debug((DEBUG_ERROR, "inet_pton failed: rv = %d, errno = %d", rv, errno));
		return 0;
	    }
	    /* ...blank out the lowest 80 bits... */
	    memset(&(ip6addr.s6_addr[6]), 0, 10);
	    /* ...and get back the "presentation format" */
	    if (inet_ntop(AF_INET6, &ip6addr, ip6buffer, INET6_ADDRSTRLEN) == NULL)
	    {
		Debug((DEBUG_ERROR, "inet_ntop failed: errno = %d", errno));
		return 0;
	    }
	    /* Now append the checksum (eg. "2001:db8::Azzurra-12345678") */
	    snprintf(virt, HOSTLEN, "%s%s%c%X",
		     ip6buffer, cloak_host, csum < 0 ? '=' : '-',
		     csum < 0 ? -csum : csum);
	    break;
	}
    }

    memcpy(dest, virt, HOSTLEN);
    return 1;
}
Пример #3
0
/******************************************************************************
 *                                                                            *
 * Function: process_rule                                                     *
 *                                                                            *
 * Purpose: process single discovery rule                                     *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void process_rule(DB_DRULE *rule)
{
	DB_RESULT	result;
	DB_ROW		row;
	DB_DCHECK	check;

	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,
		*dash = NULL;
#if defined(HAVE_IPV6)
	char	*colon;
#endif

	assert(rule);

	zabbix_log(LOG_LEVEL_DEBUG, "In process_rule() [name:%s] [range:%s]",
		rule->name,
		rule->iprange);

	for ( curr_range = rule->iprange; curr_range; curr_range = next_range )
	{ /* split by ',' */
		if ( NULL != (next_range = strchr(curr_range, ',')) )
		{
			next_range[0] = '\0';
		}

		if ( NULL != (dash = strchr(curr_range, '-')) )
		{
			dash[0] = '\0';
		}

		first = last = -1;
#if defined(HAVE_IPV6)
		if ( SUCCEED == expand_ipv6(curr_range, ip, sizeof(ip)) )
		{
			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
		{
#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[0] = ',';
			next_range ++;
		}

		if( first < 0 || last < 0 )
		{
			zabbix_log(LOG_LEVEL_WARNING, "Discovery: Wrong format of IP range [%s]",
				rule->iprange);
			continue;
		}

		for ( i = first; i <= last; 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, "Discovery: process_rule() [IP:%s]", ip);

			result = DBselect("select dcheckid,druleid,type,key_,snmp_community,ports from dchecks where druleid=" ZBX_FS_UI64,
				rule->druleid);
			while((row=DBfetch(result)))
			{
				memset(&check, 0, sizeof(DB_RESULT));

				ZBX_STR2UINT64(check.dcheckid,row[0]);
				ZBX_STR2UINT64(check.druleid,row[1]);
				check.type		= atoi(row[2]);
				check.key_		= row[3];
				check.snmp_community	= row[4];
				check.ports		= row[5];
		
				process_check(rule, &check, ip);
			}
			DBfree_result(result);

			add_host_event(ip);
		}
	}

	zabbix_log( LOG_LEVEL_DEBUG, "End process_rule()");
}
Пример #4
0
static void
process_assignment(struct ipset_iterator *iterator)
{
    while (!iterator->bdd_iterator->finished) {
        if (iterator->bdd_iterator->value == iterator->desired_value) {
            /* If the BDD iterator hasn't finished, and the result of
             * the function with this assignment matches what the caller
             * wants, then we've found an assignment to generate IP
             * addresses from.
             *
             * Try to expand this assignment, and process the first
             * expanded assignment.  We want 32 + 1 variables if the
             * current address is IPv4; 128 + 1 if it's IPv6. */

            DEBUG("Got a matching BDD assignment");
            enum ipset_tribool  address_type = ipset_assignment_get
                (iterator->bdd_iterator->assignment, 0);

            if (address_type == IPSET_FALSE) {
                /* FALSE means IPv6*/
                DEBUG("Assignment is IPv6");
                iterator->multiple_expansion_state = IPSET_ITERATOR_NORMAL;
                expand_ipv6(iterator);
                return;
            } else if (address_type == IPSET_TRUE) {
                /* TRUE means IPv4*/
                DEBUG("Assignment is IPv4");
                iterator->multiple_expansion_state = IPSET_ITERATOR_NORMAL;
                expand_ipv4(iterator);
                return;
            } else {
                /* EITHER means that this assignment contains both IPv4
                 * and IPv6 addresses.  Expand it as IPv4 first. */
                DEBUG("Assignment is both IPv4 and IPv6");
                DEBUG("Expanding IPv4 first");
                iterator->multiple_expansion_state =
                    IPSET_ITERATOR_MULTIPLE_IPV4;
                ipset_assignment_set
                    (iterator->bdd_iterator->assignment, 0, IPSET_TRUE);
                expand_ipv4(iterator);
                return;
            }
        }

        /* The BDD iterator has a value, but it doesn't match the one we
         * want.  Advance the BDD iterator and try again. */
        DEBUG("Value is %d, skipping", iterator->bdd_iterator->value);
        ipset_bdd_iterator_advance(iterator->bdd_iterator);
    }

    /* If we fall through, then the BDD iterator has finished.  That
     * means there's nothing left for the set iterator. */

    DEBUG("Set iterator is finished");
    ipset_expanded_assignment_free(iterator->assignment_iterator);
    iterator->assignment_iterator = NULL;

    ipset_bdd_iterator_free(iterator->bdd_iterator);
    iterator->bdd_iterator = NULL;
    iterator->finished = true;
}
Пример #5
0
/******************************************************************************
 *                                                                            *
 * Function: process_rule                                                     *
 *                                                                            *
 * Purpose: process single discovery rule                                     *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 ******************************************************************************/
static void	process_rule(DB_DRULE *drule)
{
	const char	*__function_name = "process_rule";
	DB_DHOST	dhost;
	int		host_status, now;
	unsigned int	j[9], i, first, last, mask, network, broadcast;
	char		ip[INTERFACE_IP_LEN_MAX], *curr_range, *next_range,
			*dash, *slash, dns[INTERFACE_DNS_LEN_MAX];
	int		ipv6;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() rule:'%s' range:'%s'", __function_name,
			drule->name, drule->iprange);

	for (curr_range = drule->iprange; curr_range; curr_range = next_range)
	{
		if (NULL != (next_range = strchr(curr_range, ',')))
			*next_range = '\0';

		zabbix_log(LOG_LEVEL_DEBUG, "%s() '%s'", __function_name, curr_range);

		if (NULL != (dash = strchr(curr_range, '-')))
			*dash = '\0';

		if (NULL != (slash = strchr(curr_range, '/')))
			*slash = '\0';

		first = last = 0;

		if (SUCCEED == expand_ipv6(curr_range, ip, sizeof(ip)))
		{
			ipv6 = 1;
#ifdef HAVE_IPV6
			if (8 == 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]))
			{
				first = (j[6] << 16) + j[7];

				if (NULL != dash)
				{
					if (1 == sscanf(dash + 1, "%x", &j[8]))
						last = (j[6] << 16) + j[8];
				}
				else if (NULL != slash)
				{
					if (1 == sscanf(slash + 1, "%d", &j[8]) && j[8] >= 112 && j[8] <= 128)
					{
						j[8] -= 96;

						mask = (32 == j[8]) ? 0xffffffff : ~(0xffffffff >> j[8]);
						network = first & mask;
						broadcast = network + ~mask;
						first = network + 1;

						zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 CIDR:%u", __function_name, j[8] + 96);
						zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x",
								0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
								(mask & 0xffff0000) >> 16, (mask & 0x0000ffff));
						zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 Netmask:'%s'",
								__function_name, collapse_ipv6(ip, sizeof(ip)));
						zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x",
								j[0], j[1], j[2], j[3], j[4], j[5],
								(network & 0xffff0000) >> 16, (network & 0x0000ffff));
						zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 Network:'%s'",
								__function_name, collapse_ipv6(ip, sizeof(ip)));
						zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x",
								j[0], j[1], j[2], j[3], j[4], j[5],
								(broadcast & 0xffff0000) >> 16, (broadcast & 0x0000ffff));
						zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 Broadcast:'%s'",
								__function_name, collapse_ipv6(ip, sizeof(ip)));

						if (j[8] <= 30)
							last = broadcast - 1;
					}
				}
				else