示例#1
0
void test_send (l2net_154 *l2, l2addr_154 *dest)
{
    Msg *m1 = initMsg(l2) ;
    Msg *m2 = initMsg(l2) ;
    bool ok ;

    option *up1 = initOptionOpaque(MO_Uri_Path, PATH1, sizeof PATH1 - 1) ;
    option *up2 = initOptionOpaque(MO_Uri_Path, PATH2, sizeof PATH2 - 1) ;
    option *up3 = initOptionOpaque(MO_Uri_Path, PATH3, sizeof PATH3 - 1) ;
    option *ocf = initOptionOpaque(MO_Content_Format, "abc", sizeof "abc" - 1) ;

    set_id (m1, 258) ;
    set_type (m1, COAP_TYPE_NON) ;
    push_option (m1, ocf) ;
    push_option (m1, up1) ;
    push_option (m1, up2) ;
    push_option (m1, up3) ;
    ok = sendMsg (m1, dest) ;
    res_send (1, ok) ;

    set_id (m2, 33) ;
    set_type (m2, COAP_TYPE_CON) ;
    push_option (m2, ocf) ;
    ok = sendMsg (m2, dest) ;
    res_send (2, ok) ;
}
示例#2
0
文件: bdd.c 项目: Ektoplasma/frontale
int bdd_send_reponse ( char *texte, int id, int code )
{
    // On prépare la réponse
    int taille = strlen ( texte ) + 20 ;
    char* reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*%d*%s*EOF*", id, code, texte ) ;

    // On chiffre la réponse
    int ilen = strlen ( reponse ) ;
    int olen = taille * 2  ;
    char* out = (char*) malloc ( olen * sizeof ( char ) ) ;
    memset ( out, '\0', olen ) ;
    if ( AES_chiffrement ( reponse, out, olen, &ilen, CHIFFREMENT ) != TRUE )
    {
        free ( reponse ) ;
        free ( out ) ;
        return ERRNO ;
    }

    // On calcul la nouvelle taille
    taille = ilen ;
    if ( ilen < 10 )
        taille += 3 ;
    else if ( ilen < 100 )
        taille += 4 ;
    else if ( ilen < 1000 )
        taille += 5 ;
    else
        taille += 6 ;

    // Finalisation de la réponse
    free ( reponse ) ;
    reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*", ilen ) ;
    if ( ilen < 10 )
        memcpy ( &reponse[2], out, ilen ) ;
    else if ( ilen < 100 )
        memcpy ( &reponse[3], out, ilen ) ;
    else if ( ilen < 1000 )
        memcpy ( &reponse[4], out, ilen ) ;
    else
        memcpy ( &reponse[5], out, ilen ) ;

    // On envoie la réponse
    res_send ( reponse, taille ) ;

    // Free
    free ( reponse ) ;
    free ( out ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}
示例#3
0
static int	dns_query(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result, int short_answer)
{
#if defined(HAVE_RES_QUERY) || defined(_WINDOWS)

	size_t			offset = 0;
	int			res, type, retrans, retry, i, ret = SYSINFO_RET_FAIL;
	char			ip[MAX_STRING_LEN], zone[MAX_STRING_LEN], tmp[MAX_STRING_LEN], buffer[MAX_STRING_LEN];
	struct in_addr		inaddr;
#ifndef _WINDOWS
	int			saved_nscount, saved_retrans, saved_retry;
	struct sockaddr_in	saved_ns;
#endif
	typedef struct
	{
		char	*name;
		int	type;
	}
	resolv_querytype_t;

	static const resolv_querytype_t	qt[] =
	{
		{"ANY",		T_ANY},
		{"A",		T_A},
		{"NS",		T_NS},
		{"MD",		T_MD},
		{"MF",		T_MF},
		{"CNAME",	T_CNAME},
		{"SOA",		T_SOA},
		{"MB",		T_MB},
		{"MG",		T_MG},
		{"MR",		T_MR},
		{"NULL",	T_NULL},
#ifndef _WINDOWS
		{"WKS",		T_WKS},
#endif
		{"PTR",		T_PTR},
		{"HINFO",	T_HINFO},
		{"MINFO",	T_MINFO},
		{"MX",		T_MX},
		{"TXT",		T_TXT},
		{"SRV",		T_SRV},
		{NULL}
	};

#ifdef _WINDOWS
	PDNS_RECORD	pQueryResults, pDnsRecord;
	LPTSTR		wzone;
	char		tmp2[MAX_STRING_LEN];
#else
	char		*name;
	unsigned char	*msg_end, *msg_ptr, *p;
	int		num_answers, num_query, q_type, q_class, q_len, value, c, n;
	struct servent	*s;
	HEADER		*hp;
	struct protoent	*pr;
#if PACKETSZ > 1024
	unsigned char	buf[PACKETSZ];
#else
	unsigned char	buf[1024];
#endif

	typedef union
	{
		HEADER		h;
#if defined(NS_PACKETSZ)
		unsigned char	buffer[NS_PACKETSZ];
#elif defined(PACKETSZ)
		unsigned char	buffer[PACKETSZ];
#else
		unsigned char	buffer[512];
#endif
	}
	answer_t;

	answer_t	answer;
#endif	/* _WINDOWS */

	*buffer = '\0';

	if (5 < num_param(param))
		return SYSINFO_RET_FAIL;

	if (0 != get_param(param, 1, ip, sizeof(ip)))
		*ip = '\0';

	if (0 != get_param(param, 2, zone, sizeof(zone)) || '\0' == *zone)
		strscpy(zone, "zabbix.com");

	if (0 != get_param(param, 3, tmp, sizeof(tmp)) || '\0' == *tmp)
		type = T_SOA;
	else
	{
		for (i = 0; NULL != qt[i].name; i++)
		{
#ifdef _WINDOWS
			if (0 == lstrcmpiA(qt[i].name, tmp))
#else
			if (0 == strcasecmp(qt[i].name, tmp))
#endif
			{
				type = qt[i].type;
				break;
			}
		}

		if (NULL == qt[i].name)
			return SYSINFO_RET_FAIL;
	}

	if (0 != get_param(param, 4, tmp, sizeof(tmp)) || '\0' == *tmp)
		retrans = 1;
	else
		retrans = atoi(tmp);

	if (0 != get_param(param, 5, tmp, sizeof(tmp)) || '\0' == *tmp)
		retry = 2;
	else
		retry = atoi(tmp);

#ifdef _WINDOWS
	wzone = zbx_utf8_to_unicode(zone);
	res = DnsQuery(wzone, type, DNS_QUERY_STANDARD, NULL, &pQueryResults, NULL);
	zbx_free(wzone);

	if (1 == short_answer)
	{
		SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1);
		ret = SYSINFO_RET_OK;
		goto clean;
	}

	if (DNS_RCODE_NOERROR != res)
		return SYSINFO_RET_FAIL;

	pDnsRecord = pQueryResults;

	while (NULL != pDnsRecord)
	{
		if (DnsSectionAnswer != pDnsRecord->Flags.S.Section)
		{
			pDnsRecord = pDnsRecord->pNext;
			continue;
		}

		if (NULL == pDnsRecord->pName)
			goto clean;

		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s",
				zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp)));
		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s",
				decode_type(pDnsRecord->wType));

		switch (pDnsRecord->wType)
		{
			case T_A:
				inaddr.s_addr = pDnsRecord->Data.A.IpAddress;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						inet_ntoa(inaddr));
				break;
			case T_NS:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MD:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MF:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_CNAME:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_SOA:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)),
						zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)),
						pDnsRecord->Data.SOA.dwSerialNo,
						pDnsRecord->Data.SOA.dwRefresh,
						pDnsRecord->Data.SOA.dwRetry,
						pDnsRecord->Data.SOA.dwExpire,
						pDnsRecord->Data.SOA.dwDefaultTtl);
				break;
			case T_MB:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MG:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MR:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_NULL:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu",
						pDnsRecord->Data.Null.dwByteCount);
				break;
			case T_PTR:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_HINFO:
				for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++)
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"",
							zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp)));
				break;
			case T_MINFO:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)),
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2)));
				break;
			case T_MX:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s",
						pDnsRecord->Data.MX.wPreference,
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp)));
				break;
			case T_TXT:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"");

				for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++)
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ",
							zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp)));

				if (0 < i)
					offset -= 1;	/* remove the trailing space */

				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\"");

				break;
			case T_SRV:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s",
						pDnsRecord->Data.SRV.wPriority,
						pDnsRecord->Data.SRV.wWeight,
						pDnsRecord->Data.SRV.wPort,
						zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp)));
				break;
			default:
				break;
		}

		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n");

		pDnsRecord = pDnsRecord->pNext;
	}
#else	/* not _WINDOWS */
	if (-1 == res_init())	/* initialize always, settings might have changed */
		return SYSINFO_RET_FAIL;

	if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf))))
		return SYSINFO_RET_FAIL;

	if ('\0' != *ip)
	{
		if (0 == inet_aton(ip, &inaddr))
			return SYSINFO_RET_FAIL;

		memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in));
		saved_nscount = _res.nscount;

		_res.nsaddr_list[0].sin_addr = inaddr;
		_res.nsaddr_list[0].sin_family = AF_INET;
		_res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT);
		_res.nscount = 1;
	}

	saved_retrans = _res.retrans;
	saved_retry = _res.retry;

	_res.retrans = retrans;
	_res.retry = retry;

	res = res_send(buf, res, answer.buffer, sizeof(answer.buffer));

	_res.retrans = saved_retrans;
	_res.retry = saved_retry;

	if ('\0' != *ip)
	{
		memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in));
		_res.nscount = saved_nscount;
	}

	hp = (HEADER *)answer.buffer;

	if (1 == short_answer)
	{
		SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1);
		return SYSINFO_RET_OK;
	}

	if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res)
		return SYSINFO_RET_FAIL;

	msg_end = answer.buffer + res;

	num_answers = ntohs(answer.h.ancount);
	num_query = ntohs(answer.h.qdcount);

	msg_ptr = answer.buffer + HFIXEDSZ;

	/* skipping query records */
	for (; 0 < num_query && msg_ptr < msg_end; num_query--)
		msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ;

	for (; 0 < num_answers && msg_ptr < msg_end; num_answers--)
	{
		if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))
			return SYSINFO_RET_FAIL;

		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name);

		GETSHORT(q_type, msg_ptr);
		GETSHORT(q_class, msg_ptr);
		msg_ptr += INT32SZ;		/* skipping TTL */
		GETSHORT(q_len, msg_ptr);
		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type));

		switch (q_type)
		{
			case T_A:
				switch (q_class)
				{
					case C_IN:
					case C_HS:
						memcpy(&inaddr, msg_ptr, INADDRSZ);
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr));
						break;
					default:
						;
				}

				msg_ptr += q_len;

				break;
			case T_NS:
			case T_CNAME:
			case T_MB:
			case T_MD:
			case T_MF:
			case T_MG:
			case T_MR:
			case T_PTR:
				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);
				break;
			case T_MX:
				GETSHORT(value, msg_ptr);	/* preference */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* exchange */
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				break;
			case T_SOA:
				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* source host */
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* administrator */
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				GETLONG(value, msg_ptr);	/* serial number */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* refresh time */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* retry time */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* expire time */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* minimum TTL */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				break;
			case T_NULL:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len);
				msg_ptr += q_len;
				break;
			case T_WKS:
				if (INT32SZ + 1 > q_len)
					return SYSINFO_RET_FAIL;

				p = msg_ptr + q_len;

				memcpy(&inaddr, msg_ptr, INADDRSZ);
				msg_ptr += INT32SZ;

				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr));

				if (NULL != (pr = getprotobynumber(*msg_ptr)))
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name);
				else
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr);

				msg_ptr++;
				n = 0;

				while (msg_ptr < p)
				{
					c = *msg_ptr++;

					do
					{
						if (0 != (c & 0200))
						{
							s = getservbyport((int)htons(n), pr ? pr->p_name : NULL);

							if (NULL != s)
								offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name);
							else
								offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n);
						}

						c <<= 1;
					}
					while (0 != (++n & 07));
				}

				break;
			case T_HINFO:
				p = msg_ptr + q_len;
				c = *msg_ptr++;

				if (0 != c)
				{
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr);
					msg_ptr += c;
				}

				if (msg_ptr < p)
				{
					c = *msg_ptr++;

					if (0 != c)
					{
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr);
						msg_ptr += c;
					}
				}

				break;
			case T_MINFO:
				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* mailbox responsible for mailing lists */
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* mailbox for error messages */
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				break;
			case T_TXT:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"");
				p = msg_ptr + q_len;

				while (msg_ptr < p)
				{
					for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--)
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++);
				}

				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\"");

				break;
			case T_SRV:
				GETSHORT(value, msg_ptr);       /* priority */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETSHORT(value, msg_ptr);       /* weight */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETSHORT(value, msg_ptr);       /* port */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* target */
					return SYSINFO_RET_FAIL;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				break;
			default:
				msg_ptr += q_len;
				break;
		}

		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n");
	}
#endif	/* _WINDOWS */

	if (0 != offset)
		buffer[--offset] = '\0';

	SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer));
	ret = SYSINFO_RET_OK;

#ifdef _WINDOWS
clean:
	if (DNS_RCODE_NOERROR == res)
		DnsRecordListFree(pQueryResults, DnsFreeRecordList);
#endif
	return ret;

#else	/* both HAVE_RES_QUERY and _WINDOWS not defined */

	return SYSINFO_RET_FAIL;

#endif	/* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */
}
示例#4
0
文件: bdd.c 项目: Ektoplasma/frontale
void bdd_send_msg ( int id, int flag, char* texte, int chiffre )
{
    // Initialisation
    char* trame = (char*) malloc ( TAILLE_MAX_TRAME * sizeof ( char ) ) ;
    memset ( trame, '\0', TAILLE_MAX_TRAME ) ;

    // On créé le message
    sprintf ( trame, "%d*%d*%s*EOF*", id, flag, texte ) ;
    int ilen = strlen ( trame ) ;

    // Chiffré ou non ?
    if ( chiffre == TRUE )
    {
        // On chiffre le message
        int olen = strlen ( trame ) * 2  ;
        char* out = (char*) malloc ( olen * sizeof ( char ) ) ;
        memset ( out, '\0', olen ) ;
        if ( AES_chiffrement ( trame, out, olen, &ilen, CHIFFREMENT ) != TRUE )
        {
            free ( out ) ;
            free ( trame ) ;
        }
        else
        {
            // On calcul la nouvelle taille
            int taille = ilen ;
            if ( ilen < 10 )
                taille += 3 ;
            else if ( ilen < 100 )
                taille += 4 ;
            else if ( ilen < 1000 )
                taille += 5 ;
            else
                taille += 6 ;

            // Finalisation de la réponse
            free ( trame ) ;
            trame = (char*) malloc ( taille * sizeof ( char ) ) ;
            memset ( trame, '\0', taille ) ;
            sprintf ( trame, "%d*", ilen ) ;
            if ( ilen < 10 )
                memcpy ( &trame[2], out, ilen ) ;
            else if ( ilen < 100 )
                memcpy ( &trame[3], out, ilen ) ;
            else if ( ilen < 1000 )
                memcpy ( &trame[4], out, ilen ) ;
            else
                memcpy ( &trame[5], out, ilen ) ;

            // On envoie la réponse
            res_send ( trame, taille ) ;

            // Free
            free ( trame ) ;
            free ( out ) ;
        }
    }
    else if ( chiffre == FALSE )
    {
        // On envoi le message
        res_send ( trame, ilen ) ;

        // Free
        free ( trame ) ;
    }
}
示例#5
0
文件: net.c 项目: zabbix/zabbix
static int	dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_answer)
{
#if defined(HAVE_RES_QUERY) || defined(_WINDOWS)

	size_t			offset = 0;
	int			res, type, retrans, retry, use_tcp, i, ret = SYSINFO_RET_FAIL, ip_type = AF_INET;
	char			*ip, zone[MAX_STRING_LEN], buffer[MAX_STRING_LEN], *zone_str, *param,
				tmp[MAX_STRING_LEN];
	struct in_addr		inaddr;
	struct in6_addr		in6addr;
#ifndef _WINDOWS
#if defined(HAVE_RES_NINIT) && !defined(_AIX)
	/* It seems that on some AIX systems with no updates installed res_ninit() can */
	/* corrupt stack (see ZBX-14559). Use res_init() on AIX. */
	struct __res_state	res_state_local;
#else	/* thread-unsafe resolver API */
	int			saved_retrans, saved_retry, saved_nscount = 0;
	unsigned long		saved_options;
	struct sockaddr_in	saved_ns;
#	if defined(HAVE_RES_U_EXT)		/* thread-unsafe resolver API /Linux/ */
	int			save_nssocks, saved_nscount6;
#	endif
#endif

#if defined(HAVE_RES_EXT_EXT)		/* AIX */
	union res_sockaddr_union	saved_ns6;
#elif defined(HAVE_RES_U_EXT_EXT)	/* BSD */
	struct sockaddr_in6		saved_ns6;
#else
	struct sockaddr_in6		*saved_ns6;
#endif
	struct sockaddr_in6	sockaddrin6;
	struct addrinfo		hint, *hres = NULL;
#endif
	typedef struct
	{
		const char	*name;
		int		type;
	}
	resolv_querytype_t;

	static const resolv_querytype_t	qt[] =
	{
		{"ANY",		T_ANY},
		{"A",		T_A},
		{"AAAA",	T_AAAA},
		{"NS",		T_NS},
		{"MD",		T_MD},
		{"MF",		T_MF},
		{"CNAME",	T_CNAME},
		{"SOA",		T_SOA},
		{"MB",		T_MB},
		{"MG",		T_MG},
		{"MR",		T_MR},
		{"NULL",	T_NULL},
#ifndef _WINDOWS
		{"WKS",		T_WKS},
#endif
		{"PTR",		T_PTR},
		{"HINFO",	T_HINFO},
		{"MINFO",	T_MINFO},
		{"MX",		T_MX},
		{"TXT",		T_TXT},
		{"SRV",		T_SRV},
		{NULL}
	};

#ifdef _WINDOWS
	PDNS_RECORD	pQueryResults, pDnsRecord;
	wchar_t		*wzone;
	char		tmp2[MAX_STRING_LEN];
	DWORD		options;
#else
	char		*name;
	unsigned char	*msg_end, *msg_ptr, *p;
	int		num_answers, num_query, q_type, q_class, q_len, value, c, n;
	struct servent	*s;
	HEADER		*hp;
	struct protoent	*pr;
#if PACKETSZ > 1024
	unsigned char	buf[PACKETSZ];
#else
	unsigned char	buf[1024];
#endif

	typedef union
	{
		HEADER		h;
#if defined(NS_PACKETSZ)
		unsigned char	buffer[NS_PACKETSZ];
#elif defined(PACKETSZ)
		unsigned char	buffer[PACKETSZ];
#else
		unsigned char	buffer[512];
#endif
	}
	answer_t;

	answer_t	answer;
#endif	/* _WINDOWS */
	zbx_vector_str_t	answers;

	*buffer = '\0';

	if (6 < request->nparam)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		return SYSINFO_RET_FAIL;
	}

	ip = get_rparam(request, 0);
	zone_str = get_rparam(request, 1);

#ifndef _WINDOWS
	memset(&hint, '\0', sizeof(hint));
	hint.ai_family = PF_UNSPEC;
	hint.ai_flags = AI_NUMERICHOST;

	if (NULL != ip && '\0' != *ip && 0 == getaddrinfo(ip, NULL, &hint, &hres) && AF_INET6 == hres->ai_family)
		ip_type = hres->ai_family;

	if (NULL != hres)
		freeaddrinfo(hres);
#endif
	if (NULL == zone_str || '\0' == *zone_str)
		strscpy(zone, "zabbix.com");
	else
		strscpy(zone, zone_str);

	param = get_rparam(request, 2);

	if (NULL == param || '\0' == *param)
		type = T_SOA;
	else
	{
		for (i = 0; NULL != qt[i].name; i++)
		{
			if (0 == strcasecmp(qt[i].name, param))
			{
				type = qt[i].type;
				break;
			}
		}

		if (NULL == qt[i].name)
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
			return SYSINFO_RET_FAIL;
		}
	}

	param = get_rparam(request, 3);

	if (NULL == param || '\0' == *param)
		retrans = 1;
	else if (SUCCEED != is_uint31(param, &retrans) || 0 == retrans)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter."));
		return SYSINFO_RET_FAIL;
	}

	param = get_rparam(request, 4);

	if (NULL == param || '\0' == *param)
		retry = 2;
	else if (SUCCEED != is_uint31(param, &retry) || 0 == retry)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter."));
		return SYSINFO_RET_FAIL;
	}

	param = get_rparam(request, 5);

	if (NULL == param || '\0' == *param || 0 == strcmp(param, "udp"))
		use_tcp = 0;
	else if (0 == strcmp(param, "tcp"))
		use_tcp = 1;
	else
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter."));
		return SYSINFO_RET_FAIL;
	}

#ifdef _WINDOWS
	options = DNS_QUERY_STANDARD | DNS_QUERY_BYPASS_CACHE;
	if (0 != use_tcp)
		options |= DNS_QUERY_USE_TCP_ONLY;

	wzone = zbx_utf8_to_unicode(zone);
	res = DnsQuery(wzone, type, options, NULL, &pQueryResults, NULL);
	zbx_free(wzone);

	if (1 == short_answer)
	{
		SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1);
		ret = SYSINFO_RET_OK;
		goto clean_dns;
	}

	if (DNS_RCODE_NOERROR != res)
	{
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot perform DNS query: [%d]", res));
		return SYSINFO_RET_FAIL;
	}

	pDnsRecord = pQueryResults;
	zbx_vector_str_create(&answers);

	while (NULL != pDnsRecord)
	{
		if (DnsSectionAnswer != pDnsRecord->Flags.S.Section)
		{
			pDnsRecord = pDnsRecord->pNext;
			continue;
		}

		if (NULL == pDnsRecord->pName)
			goto clean;

		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s",
				zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp)));
		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s",
				decode_type(pDnsRecord->wType));

		switch (pDnsRecord->wType)
		{
			case T_A:
				inaddr.s_addr = pDnsRecord->Data.A.IpAddress;
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						inet_ntoa(inaddr));
				break;
			case T_AAAA:
				memcpy(&in6addr.s6_addr, &(pDnsRecord->Data.AAAA.Ip6Address), sizeof(in6addr.s6_addr));
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_inet_ntop(AF_INET6, &in6addr, tmp, sizeof(tmp)));
				break;
			case T_NS:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MD:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MF:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_CNAME:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_SOA:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)),
						zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)),
						pDnsRecord->Data.SOA.dwSerialNo,
						pDnsRecord->Data.SOA.dwRefresh,
						pDnsRecord->Data.SOA.dwRetry,
						pDnsRecord->Data.SOA.dwExpire,
						pDnsRecord->Data.SOA.dwDefaultTtl);
				break;
			case T_MB:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MG:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_MR:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_NULL:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu",
						pDnsRecord->Data.Null.dwByteCount);
				break;
			case T_PTR:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp)));
				break;
			case T_HINFO:
				for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++)
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"",
							zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp)));
				break;
			case T_MINFO:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s",
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)),
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2)));
				break;
			case T_MX:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s",
						pDnsRecord->Data.MX.wPreference,
						zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp)));
				break;
			case T_TXT:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"");

				for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++)
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ",
							zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp)));

				if (0 < i)
					offset -= 1;	/* remove the trailing space */

				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\"");

				break;
			case T_SRV:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s",
						pDnsRecord->Data.SRV.wPriority,
						pDnsRecord->Data.SRV.wWeight,
						pDnsRecord->Data.SRV.wPort,
						zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp)));
				break;
			default:
				break;
		}

		zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n");

		pDnsRecord = pDnsRecord->pNext;
		zbx_vector_str_append(&answers, zbx_strdup(NULL, buffer));
		offset = 0;
		*buffer = '\0';
	}
#else	/* not _WINDOWS */
#if defined(HAVE_RES_NINIT) && !defined(_AIX)
	memset(&res_state_local, 0, sizeof(res_state_local));
	if (-1 == res_ninit(&res_state_local))	/* initialize always, settings might have changed */
#else
	if (-1 == res_init())	/* initialize always, settings might have changed */
#endif
	{
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot initialize DNS subsystem: %s", zbx_strerror(errno)));
		return SYSINFO_RET_FAIL;
	}

#if defined(HAVE_RES_NINIT) && !defined(_AIX)
	if (-1 == (res = res_nmkquery(&res_state_local, QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf))))
#else
	if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf))))
#endif
	{
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot create DNS query: %s", zbx_strerror(errno)));
		return SYSINFO_RET_FAIL;
	}

	if (NULL != ip && '\0' != *ip && AF_INET == ip_type)
	{
		if (0 == inet_aton(ip, &inaddr))
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IP address."));
			return SYSINFO_RET_FAIL;
		}

#if defined(HAVE_RES_NINIT) && !defined(_AIX)
		res_state_local.nsaddr_list[0].sin_addr = inaddr;
		res_state_local.nsaddr_list[0].sin_family = AF_INET;
		res_state_local.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT);
		res_state_local.nscount = 1;
#else	/* thread-unsafe resolver API */
		memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in));
		saved_nscount = _res.nscount;

		_res.nsaddr_list[0].sin_addr = inaddr;
		_res.nsaddr_list[0].sin_family = AF_INET;
		_res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT);
		_res.nscount = 1;
#endif
	}
	else if (NULL != ip && '\0' != *ip && AF_INET6 == ip_type)
	{
		if (0 == inet_pton(ip_type, ip, &in6addr))
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IPv6 address."));
			return SYSINFO_RET_FAIL;
		}

		memset(&sockaddrin6, '\0', sizeof(sockaddrin6));
#if defined(HAVE_RES_SIN6_LEN)
		sockaddrin6.sin6_len = sizeof(sockaddrin6);
#endif
		sockaddrin6.sin6_family = AF_INET6;
		sockaddrin6.sin6_addr = in6addr;
		sockaddrin6.sin6_port = htons(ZBX_DEFAULT_DNS_PORT);
#if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT))
		memset(&res_state_local.nsaddr_list[0], '\0', sizeof(res_state_local.nsaddr_list[0]));
#		ifdef HAVE_RES_U_EXT			/* Linux */
		saved_ns6 = res_state_local._u._ext.nsaddrs[0];
		res_state_local._u._ext.nsaddrs[0] = &sockaddrin6;
		res_state_local._u._ext.nssocks[0] = -1;
		res_state_local._u._ext.nscount6 = 1;	/* CentOS */
#		elif HAVE_RES_U_EXT_EXT			/* BSD */
		if (NULL != res_state_local._u._ext.ext)
			memcpy(res_state_local._u._ext.ext, &sockaddrin6, sizeof(sockaddrin6));

		res_state_local.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT);
#		endif
		res_state_local.nscount = 1;
#else
		memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in));
		saved_nscount = _res.nscount;
#		if defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT) || defined(HAVE_RES_EXT_EXT)
		memset(&_res.nsaddr_list[0], '\0', sizeof(_res.nsaddr_list[0]));
		_res.nscount = 1;
#		endif
#		if defined(HAVE_RES_U_EXT)		/* thread-unsafe resolver API /Linux/ */
		saved_nscount6 = _res._u._ext.nscount6;
		saved_ns6 = _res._u._ext.nsaddrs[0];
		save_nssocks = _res._u._ext.nssocks[0];
		_res._u._ext.nsaddrs[0] = &sockaddrin6;
		_res._u._ext.nssocks[0] = -1;
		_res._u._ext.nscount6 = 1;
#		elif defined(HAVE_RES_U_EXT_EXT)	/* thread-unsafe resolver API /BSD/ */
		memcpy(&saved_ns6, _res._u._ext.ext, sizeof(saved_ns6));
		_res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT);

		if (NULL != _res._u._ext.ext)
			memcpy(_res._u._ext.ext, &sockaddrin6, sizeof(sockaddrin6));
#		elif defined(HAVE_RES_EXT_EXT)		/* thread-unsafe resolver API /AIX/ */
		memcpy(&saved_ns6, &(_res._ext.ext.nsaddrs[0]), sizeof(saved_ns6));
		memcpy(&_res._ext.ext.nsaddrs[0], &sockaddrin6, sizeof(sockaddrin6));
#		endif /* #if defined(HAVE_RES_U_EXT) */
#endif /* #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) */
	}

#if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT))
	if (0 != use_tcp)
		res_state_local.options |= RES_USEVC;

	res_state_local.retrans = retrans;
	res_state_local.retry = retry;

	res = res_nsend(&res_state_local, buf, res, answer.buffer, sizeof(answer.buffer));

#	ifdef HAVE_RES_U_EXT	/* Linux */
	if (NULL != ip && '\0' != *ip && AF_INET6 == ip_type)
		res_state_local._u._ext.nsaddrs[0] = saved_ns6;
#	endif
#	ifdef HAVE_RES_NDESTROY
	res_ndestroy(&res_state_local);
#	else
	res_nclose(&res_state_local);
#	endif
#else	/* thread-unsafe resolver API */
	saved_options = _res.options;
	saved_retrans = _res.retrans;
	saved_retry = _res.retry;

	if (0 != use_tcp)
		_res.options |= RES_USEVC;

	_res.retrans = retrans;
	_res.retry = retry;

	res = res_send(buf, res, answer.buffer, sizeof(answer.buffer));

	_res.options = saved_options;
	_res.retrans = saved_retrans;
	_res.retry = saved_retry;

	if (NULL != ip && '\0' != *ip)
	{
		if (AF_INET6 == ip_type)
		{
#			if defined(HAVE_RES_U_EXT)		/* Linux */
			_res._u._ext.nsaddrs[0] = saved_ns6;
			_res._u._ext.nssocks[0] = save_nssocks;
			_res._u._ext.nscount6 = saved_nscount6;
#			elif defined(HAVE_RES_U_EXT_EXT)	/* BSD */
			if (NULL != _res._u._ext.ext)
				memcpy(_res._u._ext.ext, &saved_ns6, sizeof(saved_ns6));
#			elif defined(HAVE_RES_EXT_EXT)		/* AIX */
			memcpy(&_res._ext.ext.nsaddrs[0], &saved_ns6, sizeof(saved_ns6));
#			endif
		}

		memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in));
		_res.nscount = saved_nscount;
	}
#endif
	hp = (HEADER *)answer.buffer;

	if (1 == short_answer)
	{
		SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1);
		return SYSINFO_RET_OK;
	}

	if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot perform DNS query."));
		return SYSINFO_RET_FAIL;
	}

	msg_end = answer.buffer + res;

	num_answers = ntohs(answer.h.ancount);
	num_query = ntohs(answer.h.qdcount);

	msg_ptr = answer.buffer + HFIXEDSZ;
	zbx_vector_str_create(&answers);

	/* skipping query records */
	for (; 0 < num_query && msg_ptr < msg_end; num_query--)
		msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ;

	for (; 0 < num_answers && msg_ptr < msg_end; num_answers--)
	{
		if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
			ret = SYSINFO_RET_FAIL;
			goto clean;
		}

		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name);

		GETSHORT(q_type, msg_ptr);
		GETSHORT(q_class, msg_ptr);
		msg_ptr += INT32SZ;		/* skipping TTL */
		GETSHORT(q_len, msg_ptr);
		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type));

		switch (q_type)
		{
			case T_A:
				switch (q_class)
				{
					case C_IN:
					case C_HS:
						memcpy(&inaddr, msg_ptr, INADDRSZ);
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
								inet_ntoa(inaddr));
						break;
					default:
						;
				}

				msg_ptr += q_len;

				break;
			case T_AAAA:
				switch (q_class)
				{
					case C_IN:
					case C_HS:
						memcpy(&in6addr, msg_ptr, IN6ADDRSZ);
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s",
								inet_ntop(AF_INET6, &in6addr, tmp, sizeof(tmp)));
						break;
					default:
						;
				}

				msg_ptr += q_len;

				break;
			case T_NS:
			case T_CNAME:
			case T_MB:
			case T_MD:
			case T_MF:
			case T_MG:
			case T_MR:
			case T_PTR:
				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);
				break;
			case T_MX:
				GETSHORT(value, msg_ptr);	/* preference */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* exchange */
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				break;
			case T_SOA:
				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* source host */
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* administrator */
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				GETLONG(value, msg_ptr);	/* serial number */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* refresh time */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* retry time */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* expire time */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETLONG(value, msg_ptr);	/* minimum TTL */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				break;
			case T_NULL:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len);
				msg_ptr += q_len;
				break;
			case T_WKS:
				if (INT32SZ + 1 > q_len)
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}

				p = msg_ptr + q_len;

				memcpy(&inaddr, msg_ptr, INADDRSZ);
				msg_ptr += INT32SZ;

				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr));

				if (NULL != (pr = getprotobynumber(*msg_ptr)))
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name);
				else
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr);

				msg_ptr++;
				n = 0;

				while (msg_ptr < p)
				{
					c = *msg_ptr++;

					do
					{
						if (0 != (c & 0200))
						{
							s = getservbyport((int)htons(n), pr ? pr->p_name : NULL);

							if (NULL != s)
								offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name);
							else
								offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n);
						}

						c <<= 1;
					}
					while (0 != (++n & 07));
				}

				break;
			case T_HINFO:
				p = msg_ptr + q_len;
				c = *msg_ptr++;

				if (0 != c)
				{
					offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr);
					msg_ptr += c;
				}

				if (msg_ptr < p)
				{
					c = *msg_ptr++;

					if (0 != c)
					{
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr);
						msg_ptr += c;
					}
				}

				break;
			case T_MINFO:
				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* mailbox responsible for mailing lists */
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* mailbox for error messages */
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				break;
			case T_TXT:
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"");
				p = msg_ptr + q_len;

				while (msg_ptr < p)
				{
					for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--)
						offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++);
				}

				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\"");

				break;
			case T_SRV:
				GETSHORT(value, msg_ptr);       /* priority */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETSHORT(value, msg_ptr);       /* weight */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				GETSHORT(value, msg_ptr);       /* port */
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);

				if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))	/* target */
				{
					SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
					return SYSINFO_RET_FAIL;
				}
				offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

				break;
			default:
				msg_ptr += q_len;
				break;
		}

		zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n");

		zbx_vector_str_append(&answers, zbx_strdup(NULL, buffer));
		offset = 0;
		*buffer = '\0';
	}
#endif	/* _WINDOWS */

	zbx_vector_str_sort(&answers, ZBX_DEFAULT_STR_COMPARE_FUNC);

	for (i = 0; i < answers.values_num; i++)
		offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s", answers.values[i]);

	if (0 != offset)
		buffer[--offset] = '\0';

	SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer));
	ret = SYSINFO_RET_OK;

clean:
	zbx_vector_str_clear_ext(&answers, zbx_str_free);
	zbx_vector_str_destroy(&answers);
#ifdef _WINDOWS
clean_dns:
	if (DNS_RCODE_NOERROR == res)
		DnsRecordListFree(pQueryResults, DnsFreeRecordList);
#endif

	return ret;

#else	/* both HAVE_RES_QUERY and _WINDOWS not defined */

	return SYSINFO_RET_FAIL;

#endif	/* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */
}
示例#6
0
文件: resolv.c 项目: hahtse/Leben
main ()
{
 int i, j, hl, rc, qc, ac, p, a;
 int op, class, type, datalen, buflen, msgl;
 u_short qtype, qclass, rtype, rclass, l, l2;
 u_long rttl;
 u_char buf[100], *cp;
 char dn[100], *dname, *z, ping[50];
 struct rrec newrr, *rec;
 union {
	char cdat[4];
	unsigned long ldat;
	struct in_addr adat;
 } dat;
 union {
	u_char data[DATALEN];
	HEADER head;
 } data;

  hl = sizeof (HEADER);
  signal (SIGALRM, tfunc);
  res_init();
  printf ("Inhalt von resolv.conf\n");
  printf ("domain: %s\n", _res.defdname);
 /* printf ("MAXDNSRCH = %d\n", MAXDNSRCH);
  for (i=0; i<MAXDNSRCH; i++)
	printf ("%s\n", _res.dnsrch[i]);
*/
  printf ("%d Name-Server\n", MAXNS);
  for (i=0; i<MAXNS; i++)
  	printf ("%s\n", inet_ntoa(_res.nsaddr_list[i].sin_addr));
/*  printf ("number of addresses: %d \n", _res.ascount);
  printf ("number of name servers: %d \n", _res.nscount);
*/
  /*printf ("%d %s\n", _res.ascount, inet_ntoa(_res.sort_list[0]));*/
 
/*  strcpy (dn, "zeus.rz.htwk-leipzig.de");  */
/*  strcpy (dn, "caramba.cs.tu-berlin.de"); */ 
/*  strcpy (dn, "ftp.cs.tu-berlin.de");  */
/*  strcpy (dn, "moses.imn.htwk-leipzig.de"); */
/*  strcpy (dn, "moses"); */

 do {
  printf ("\nSuche nach IP-Adresse von\n");
  printf ("Hostname: ");
  z = gets (dn); 
  printf ("\n");
 if (z) {
  dname = dn;
  strcpy (data.data, dn);
  datalen = strlen(dn)+1;
  op = QUERY;
  buflen = sizeof(buf);
/*  _res.options |= RES_DEBUG; */
  _res.retrans = 10;
  _res.retry = 2; 
  class = C_IN; 
  type = T_A; 
  rc=res_mkquery (op, dname, class, type, data.data, datalen, &newrr, buf, buflen);

  buflen = rc;
  alarm (10);
  msgl=res_send (buf, buflen, data.data, DATALEN);
  if (msgl>0) {

/*  printf ("\nsend: %d\n", msgl); */
/* for (i=0; i< msgl; i++) {
	for (j=0; j<4; j++) dat.cdat[j] = data.data[i+j];
*/
/*	printf ("%x ", dat.ldat); 
	if (dat.ldat==x) printf ("\n%d %x\n", i, dat.ldat); 
  }
  printf ("\n");
*/
/*  for (i=0; i< msgl;i++) {
	j = data.data[i] & 0xff; printf ("%2x ", j); 
  } 
  printf ("\n");
  for (i=0; i< msgl;i++) if (data.data[i]>31) printf ("%c ", data.data[i]);
  printf ("\n");
*/
/*  printf ("%x \n", x); 
*/
  ac = data.head.ancount;
  qc = data.head.qdcount;
  p = hl;
  printf ("Query\n");
  while (qc) {
    l = data.data[p];
    while (l > 0 && l < 64) {
/*	printf ("%d \n", p); */
	for (i=1; i<=l; i++) putchar (data.data[p+i]);	       	
	p = p + l + 1;
	l = data.data[p];
	if (l) putchar ('.');
    } 
    putchar ('\n');
    p++;
    cp = data.data+p; /* GETSHORT verlangt Pointervariable !! */
/* einfache Zuweisung (auch mit cast) ergibt falsche Werte
   evtl. Probleme mit integralen Grenzen ?? */
    GETSHORT (qtype, cp); 
/* oder: qtype = _getshort(data.data+p);*/
    p = p + sizeof(u_short);
    cp = data.data+p;
    GETSHORT (qclass, cp); 
    p = p + sizeof(u_short);
    cp = data.data+p;
    printf ("QTYPE=%d, QCLASS=%d", qtype, qclass);
    qc--;
    putchar ('\n');
  }
  printf ("\n%d Answers\n", ac);
  a=1;
  while (ac) {
    printf ("%d.\n", a);
    l = data.data[p];
    while (l > 0 && l < 64) {
/*	printf ("%d \n", p); */
	for (i=1; i<=l; i++) putchar (data.data[p+i]);	       	
	p = p + l + 1;
	l = data.data[p];
	if (l) putchar ('.');
	else putchar ('\n');
    }
    if (l>63) {
	rc=dn_expand (data.data, data.data+msgl, cp, buf, buflen);
	printf ("%s\n", buf);
	p += 2;
    }  else p++;
    cp = data.data+p;
    GETSHORT (rtype, cp); 
    p = p + sizeof(u_short);
    cp = data.data+p;
    GETSHORT (rclass, cp); 
    p = p + sizeof(u_short);
    cp = data.data+p;
    GETLONG (rttl, cp);
    p = p + sizeof(u_long);
    printf ("RRTYPE=%d, RRCLASS=%d RRTTL=%d\n", rtype, rclass, rttl);
    cp = data.data+p;
    GETSHORT (l, cp);
    p = p + sizeof(u_short);
    if (rtype == 1) {
    	for (j = 0; j< l; j++) dat.cdat[j] = data.data[p+j];
/*	printf ("IP-Adresse: %x \n", dat.ldat); */
    	printf ("IP-Adresse: %s \n", inet_ntoa (dat.adat));
    	sprintf (buf, "%s", inet_ntoa (dat.adat));
	strcpy (ping, "ping ");
	strcat (ping, buf);
	strcat (ping, " 10");
	printf ("%s\n", ping);
	system (ping);
	p += l;
    } 
    if (rtype == 5) {
	l2 = l;
	l = data.data[p];
	while (l > 0 && l < 64) {
/*		printf ("%d \n", p); */
		for (i=1; i<=l; i++) putchar (data.data[p+i]);	       	
		p = p + l + 1;
		l = data.data[p];
		if (l) putchar ('.');
		else putchar('\n');
    	}
    	if (l>63) {
		rc=dn_expand (data.data, data.data+msgl, cp, buf, buflen);
		printf ("%s\n", buf);
		p += 2;
    	}  else p++;
	l = l2;
    }
    putchar ('\n');
    ac--; a++;
    }
   } else printf ("not found\n");
 } } while (z);
}
示例#7
0
int bdd_do_insert ( char *safe_trame )
{
    // Déclaration variable
    Ref modele ;                    // Modèle propre à la trame qui sera appliqué en requête sur la BDD
    char* morceau = NULL ;          // Variable contenant chaque morceau de la trame (strtok_r)
    char* safe_morceau = NULL ;     // Variable contenant chaque morceau de la trame (strtok_r)
    char* groupes = NULL ;
    char* groupes_test = NULL ;
    int groupes_free = FALSE ;
    char* valeur = NULL ;
    char* user = NULL ;
    char* politiques = NULL ;
    char* politiques_test = NULL ;
    int politiques_free = FALSE ;
    int cpt = 0 ;                   // Compteur

    // On découpe les 7 éléments restant de notre trame
    for ( cpt = 0; cpt < 7; cpt++ )
    {
        // On découpe la trame en morceaux repérés via un "*"
        if ( ( morceau = strtok_r ( NULL, "*", &safe_trame ) ) == NULL )
        {
            perror ( "Erreur_bdd_do_insert : information manquante " ) ;
            if ( politiques_free == TRUE )
                free ( politiques ) ;
            if ( groupes_free == TRUE )
                free ( groupes ) ;
            bdd_send_msg ( INSERT, "ERROR" ) ;
            return ERRNO ;
        }

        // On vérifie que l'information est présente
        if ( strcmp ( morceau, "EOF") == 0 )
        {
            perror ( "Erreur_bdd_do_insert : information manquante II " ) ;
            if ( politiques_free == TRUE )
                free ( politiques ) ;
            if ( groupes_free == TRUE )
                free ( groupes ) ;
            bdd_send_msg ( INSERT, "ERROR" ) ;
            return ERRNO ;
        }
        else
        {
            // On affecte l'information
            switch ( cpt )
            {
                case ZERO :
                    modele.statut =  multiple ( calculate_SHA256 ( morceau ) ) ;
                    break ;

                case UN :
                    modele.affectation =  multiple ( calculate_SHA256 ( morceau ) ) ;
                    break ;

                case DEUX :
                    groupes_test = morceau ;
                    groupes = (char*) malloc ( ( strlen ( groupes_test ) + 1 ) * sizeof ( char ) ) ;
                    memset ( groupes, '\0', strlen ( groupes_test ) + 1 ) ;
                    sprintf ( groupes, "%s", groupes_test ) ;
                    groupes_free = TRUE ;
                    break ;

                case TROIS :
                    modele.type =  multiple ( calculate_SHA256 ( morceau ) ) ;
                    break ;

                case QUATRE :
                    valeur = morceau ;
                    break ;

                case CINQ :
                    user = morceau ;
                    break ;

                case SIX :
                    politiques_test = morceau ;
                    politiques = (char*) malloc ( ( strlen ( politiques_test ) + 1 ) * sizeof ( char ) ) ;
                    memset ( politiques, '\0', strlen ( politiques_test ) + 1 ) ;
                    sprintf ( politiques, "%s", politiques_test ) ;
                    politiques_free = TRUE ;
                    break ;

                default :
                    perror ( "Erreur_do_insert : overflow compteur cpt " ) ;
                    if ( politiques_free == TRUE )
                        free ( politiques ) ;
                    if ( groupes_free == TRUE )
                        free ( groupes ) ;
                    bdd_send_msg ( INSERT, "ERROR" ) ;
                    return ERRNO ;
                    break ;
            }
        }
    }

    // On vérifie le format des politiques
    morceau = NULL ;
    cpt = 0 ;
    do
    {
        // On découpe
        if ( cpt == 0 )
            morceau = strtok_r ( politiques_test, "$", &safe_morceau ) ;
        else
            morceau = strtok_r ( NULL, "$", &safe_morceau ) ;

        // On inc cpt
        cpt++ ;
    } while ( morceau != NULL ) ;
    if ( cpt != 4 )
    {
        perror ( "Erreur_bdd_do_insert : politiques() " ) ;
        free ( politiques ) ;
        free ( groupes ) ;
        bdd_send_msg ( INSERT, "ERROR" ) ;
        return ERRNO ;
    }

    // On compte le nombre de groupes
    morceau = NULL ;
    safe_morceau = NULL ;
    int nbr_grp = 0 ;
    do
    {
        // On découpe
        if ( nbr_grp == 0 )
            morceau = strtok_r ( groupes_test, ";", &safe_morceau ) ;
        else
            morceau = strtok_r ( NULL, ";", &safe_morceau ) ;

        // On inc cpt
        nbr_grp++ ;
    } while ( morceau != NULL ) ;

    // PHASE 2
    // Déclaration variables
    char* reference_str = NULL ;
    char* valeur_finale = NULL ;
    char* reponse = NULL ;
    char* temporaire = NULL ;
    int first = TRUE ;
    unsigned long taille = 0 ;

    // Ini
    reference_str = (char*) malloc ( TAILLE_MAX_REF * sizeof ( char ) ) ;
    memset ( reference_str, '\0', TAILLE_MAX_REF ) ;
    taille = strlen ( valeur ) + strlen ( user ) + strlen ( politiques ) + 3 ;
    valeur_finale = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( valeur_finale, '\0', taille ) ;
    temporaire = (char*) malloc ( TAILLE_MAX_REF * nbr_grp * sizeof ( char ) ) ;
    memset ( temporaire, '\0', TAILLE_MAX_REF * nbr_grp ) ;

    // On créé autant de référence qu'il y a de groupes
    morceau = NULL ;
    safe_morceau = NULL ;
    cpt = 0 ;
    do
    {
        // On découpe
        if ( cpt == 0 )
            morceau = strtok_r ( groupes, ";", &safe_morceau ) ;
        else
            morceau = strtok_r ( NULL, ";", &safe_morceau ) ;

        // On vérifie
        if ( morceau != NULL )
        {
            // On prépare la référénce qui va être inséreée en BDD
            modele.groupe =  multiple ( calculate_SHA256 ( morceau ) ) ;
            memset ( reference_str, '\0', TAILLE_MAX_REF ) ;
            if ( ref_concatenation ( &modele, reference_str )  == ERRNO )
            {
                perror ( "Erreur_bdd_do_insert : ref_concatenation() " ) ;
                free ( politiques ) ;
                free ( reference_str ) ;
                free ( valeur_finale ) ;
                free ( groupes ) ;
                free ( temporaire ) ;
                bdd_send_msg ( INSERT, "ERROR" ) ;
                return ERRNO ;
            }

            // On prépare la valeur_final qui va être insrérée en BDD
            memset ( valeur_finale, '\0', taille ) ;
            sprintf ( valeur_finale, "%s*%s*%s", user, valeur, politiques ) ;

            // On réalise l'insertion
            if ( bdd_do_request ( mysql_bdd, INSERT, reference_str, valeur_finale, NULL ) == ERRNO )
            {
                perror ( "Erreur_bdd_do_insert : bdd_do_request() " ) ;
                free ( politiques ) ;
                free ( reference_str ) ;
                free ( valeur_finale ) ;
                free ( groupes ) ;
                free ( temporaire ) ;
                bdd_send_msg ( INSERT, "ERROR" ) ;
                return ERRNO ;
            }
            else
                nbr_tuples++ ;

            // On ajoute la référence à la réponse
            if ( first == TRUE )
            {
                sprintf ( temporaire, "%s", reference_str ) ;
                first = FALSE ;
            }
            else if ( first == FALSE )
                sprintf ( temporaire + strlen ( temporaire ), ";%s", reference_str ) ;

            // On inc cpt
            cpt++ ;
        }
    } while ( morceau != NULL ) ;

    // On envoie la réponse
    taille = strlen ( temporaire ) + 10 ;
    reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*%s*EOF", INSERT, temporaire ) ;
    res_send ( reponse ) ;

    // Free
    free ( politiques ) ;
    free ( reference_str ) ;
    free ( valeur_finale ) ;
    free ( groupes ) ;
    free ( temporaire ) ;
    free ( reponse ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}
示例#8
0
int bdd_search_modele ( MYSQL_RES* resultat_req, Ref* modele )
{
    // Initialisation
    Ref reference ;
    int return_value ;
    int suite = TRUE ;
    MYSQL_ROW tuple ;
    char* user = NULL ;
    char* safe_tuple = NULL ;              // Permet d'appeler strtok_r sur le bon contenu.
    char* reponse = NULL ;
    int first = TRUE ;

    // Initialisation
    user = (char*) malloc ( TAILLE_HASH_NOM * sizeof ( char ) ) ;
    memset ( user, '\0', TAILLE_HASH_NOM ) ;

    // Initialisation
    char* output = (char*) malloc ( RSA_size ( bdd_key ) * sizeof ( char ) ) ;
    memset ( output, '\0', RSA_size ( bdd_key ) ) ;

    // Initialisation
    char* temporaire = (char*) malloc ( ( TAILLE_MAX_REF + TAILLE_HASH_NOM + 3 ) * nbr_tuples * sizeof ( char ) ) ;
    memset ( temporaire, '\0', ( TAILLE_MAX_REF + TAILLE_HASH_NOM + 3 ) * nbr_tuples ) ;

    // On parcourt chaque tuple
    while ( suite == TRUE )
    {
        // On récupère un tuple
        if ( ( tuple = mysql_fetch_row ( resultat_req ) ) ==  NULL )
            suite = FALSE ;

        // On le traite
        if ( suite == TRUE )
        {
            // On découpe la référence
            if ( ( return_value = ref_split ( tuple[0], &reference ) ) == ERRNO )
            {
                perror ( "Erreur_bdd_search_modele : ref_split " ) ;
                free ( user ) ;
                free ( output ) ;
                bdd_send_msg ( SEEK, "ERROR" ) ;
                return ERRNO ;
            }

            // On regarde si elle correspond à ce que l'on recherche
            if ( ( return_value = ref_cmp ( &reference, modele ) ) == ERRNO )
            {
                perror ( "Erreur_bdd_traitement_request : ref_cmp " ) ;
                free ( user ) ;
                free ( output ) ;
                bdd_send_msg ( SEEK, "ERROR" ) ;
                return ERRNO ;
            }
            else if ( return_value == TRUE )    // La référence nous intéresse
            {

                // On déchiffre le tuple
                memset ( output, '\0', RSA_size ( bdd_key ) ) ;
                if ( RSA_chiffrement ( (unsigned char*) tuple[1], (unsigned char*) output, DECHIFFREMENT ) != TRUE )
                {
                    perror ( "Erreur_bdd_serach_modele : RSA_dechiffrement " ) ;
                    free ( output ) ;
                    free ( user ) ;
                    bdd_send_msg ( SEEK, "ERROR" ) ;
                    return ERRNO ;
                }

                // On récupère le hash du nom associé
                memset ( user, '\0', TAILLE_HASH_NOM ) ;
                sprintf ( user, "%s", strtok_r ( output, "*", &safe_tuple ) ) ;

                // On ajoute la référence et le nom associé à la réponse
                if ( first == TRUE )
                {
                    sprintf ( temporaire, "%s;%s", tuple[0], user ) ;
                    first = FALSE ;
                }
                else if ( first == FALSE )
                    sprintf ( temporaire + strlen ( temporaire ), "*%s;%s", tuple[0], user ) ;
            }
        }
    }

    // On envoie la réponse
    int taille = strlen ( temporaire ) + 10 ;
    reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*%s*EOF", SEEK, temporaire ) ;
    res_send ( reponse ) ;

    // Free
    free ( output ) ;
    free ( user ) ;
    free ( temporaire ) ;
    free ( reponse ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}
示例#9
0
int bdd_do_select ( char *safe_trame )
{
    // Déclaration variable
    char* morceau = NULL ;          // Variable contenant chaque morceau de la trame (strtok_r)
    char* statut = NULL ;
    char* affectation = NULL ;
    char* groupes = NULL ;
    char* reference = NULL ;
    int cpt = 0 ;                   // Compteur
    MYSQL_RES* resultat_req ;       // Object MYSQL décrivant le résultat d'une requête
    MYSQL_ROW tuple ;               // Object MYSQL décrivant un tuple dans la liste résultat
    char* safe_tuple = NULL ;       // Permet d'appeler strtok_r sur le bon contenu.
    char* valeur = NULL ;
    char* politique = NULL ;
    int code_retour = 0 ;

    // On découpe les 4 éléments restant de notre trame
    for ( cpt = 0; cpt < 4; cpt++ )
    {
        // On découpe la trame en morceaux repérés via un "*"
        if ( ( morceau = strtok_r ( NULL, "*", &safe_trame ) ) == NULL )
        {
            perror ( "Erreur_bdd_do_select : information manquante " ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }

        // On vérifie que l'information est présente
        if ( strcmp ( morceau, "EOF") == 0 )
        {
            perror ( "Erreur_bdd_do_select : information manquante II" ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }
        else
        {
            // On affecte l'information
            switch ( cpt )
            {
                case ZERO :
                    statut = morceau ;
                    break ;

                case UN :
                    affectation = morceau ;
                    break ;

                case DEUX :
                    groupes = morceau ;
                    break ;

                case TROIS :
                    reference = morceau ;
                    break ;

                default :
                    perror ( "Erreur_do_select : overflow compteur cpt " ) ;
                    bdd_send_msg ( SELECT, "ERROR" ) ;
                    return ERRNO ;
                    break ;
            }
        }
    }

    // On récupère auprès de la BDD, la valeur associée à cette référence
    if ( bdd_do_request ( mysql_bdd, SELECT, reference, NULL, &resultat_req ) == ERRNO )
    {
        perror ( "Erreur_bdd_do_select : bad requete " ) ;
        mysql_free_result ( resultat_req ) ;
        bdd_send_msg ( SELECT, "ERROR" ) ;
        return ERRNO ;
    }

    // On récupère le tuple
    if ( ( tuple = mysql_fetch_row ( resultat_req ) ) ==  NULL )
    {
        perror ( "Erreur_bdd_do_select : bad tuple " ) ;
        mysql_free_result ( resultat_req ) ;
        bdd_send_msg ( SELECT, "ERROR" ) ;
        return ERRNO ;
    }

    // On déchiffre le tuple
    char* output = (char*) malloc ( RSA_size ( bdd_key ) * sizeof ( char ) ) ;
    memset ( output, '\0', RSA_size ( bdd_key ) ) ;
    if ( RSA_chiffrement ( (unsigned char*) tuple[0], (unsigned char*) output, DECHIFFREMENT ) != TRUE )
    {
        perror ( "Erreur_bdd_do_select : RSA_dechiffrement " ) ;
        free ( output ) ;
        mysql_free_result ( resultat_req ) ;
        bdd_send_msg ( SELECT, "ERROR" ) ;
        return ERRNO ;
    }

    // On récupère les 3 informations du tuple
    morceau = NULL ;
    for ( cpt = 0; cpt < 3; cpt++ )
    {
        // On découpe le tuple en morceaux repérés via un "*"
        if ( cpt == 0 )
            morceau = strtok_r ( output, "*", &safe_tuple ) ;
        else
            morceau = strtok_r ( NULL, "*", &safe_tuple ) ;

        // Vérification
        if ( morceau == NULL )
        {
            perror ( "Erreur_bdd_do_select : information manquante III " ) ;
            free ( output ) ;
            mysql_free_result ( resultat_req ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }

        // On affecte l'information
        switch ( cpt )
        {
            case ZERO :
                break ;

            case UN :
                valeur = morceau ;
                break ;

            case DEUX :
                politique = morceau ;
                break ;

            default :
                perror ( "Erreur_do_select : overflow compteur cpt " ) ;
                free ( output ) ;
                mysql_free_result ( resultat_req ) ;
                bdd_send_msg ( SELECT, "ERROR" ) ;
                return ERRNO ;
                break ;
        }
    }

    // On regarde les politique de partage de la ressource
    morceau = NULL ;
    safe_tuple = NULL ;
    for ( cpt = 0; cpt < 3; cpt++ )
    {
        // On découpe les politiques de partage en morceaux repérés via un "$"
        if ( cpt == 0 )
            morceau = strtok_r ( politique, "$", &safe_tuple ) ;
        else
            morceau = strtok_r ( NULL, "$", &safe_tuple ) ;
        if ( morceau == NULL )
        {
            perror ( "Erreur_bdd_do_select : information manquante IV " ) ;
            free ( output ) ;
            mysql_free_result ( resultat_req ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }

        // On regarde d'abord si on est en accès interdit
        if ( strcmp ( morceau, "-" ) == 0 )
        {
            printf ( "Erreur_bdd_do_select : BAD-PERMISSION " ) ;
            free ( output ) ;
            mysql_free_result ( resultat_req ) ;
            bdd_send_msg ( SELECT, "BAD-PERMISSION" ) ;
            return FALSE ;
        }
        else if ( strcmp ( morceau, "+") != 0 ) // Puis si on n'est pas en accès total
        {
            // Alors on traite le cas par cas
            switch ( cpt )
            {
                case ZERO : // Statut
                    code_retour = bdd_verification_partage ( morceau, statut ) ;
                    break ;

                case UN :   // Affectation
                    code_retour = bdd_verification_partage ( morceau, affectation ) ;
                    break ;

                case DEUX : // Groupes
                    code_retour = bdd_verification_partage ( morceau, groupes ) ;
                    break ;

                default :
                    perror ( "Erreur_do_select : overflow compteur cpt " ) ;
                    free ( output ) ;
                    mysql_free_result ( resultat_req ) ;
                    bdd_send_msg ( SELECT, "ERROR" ) ;
                    return ERRNO ;
                    break ;
            }

            // On vérifie le code retour
            if ( code_retour == FALSE )
            {
                printf ( "Erreur_bdd_do_select : bad permission " ) ;
                free ( output ) ;
                mysql_free_result ( resultat_req ) ;
                bdd_send_msg ( SELECT, "BAD-PERMISSION" ) ;
                return FALSE ;
            }
            else if ( code_retour == ERRNO )
            {
                printf ( "Erreur_bdd_do_select : bdd_verification_partage " ) ;
                free ( output ) ;
                mysql_free_result ( resultat_req ) ;
                bdd_send_msg ( SELECT, "ERROR" ) ;
                return ERRNO ;
            }
        }
    }

    // Si on arrive ici c'est que la poltique de partage est respectée : on retourne la valeur
    int taille = strlen ( valeur ) + 10 ;
    char* reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*%s*EOF", SELECT, valeur ) ;
    res_send ( reponse ) ;

    // On free l'espace de résultat
    free ( output ) ;
    mysql_free_result ( resultat_req ) ;
    free ( reponse ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}