Beispiel #1
0
/*
*TODO: Check for and handle [_res.options & RES_USE_INET6]
*/
static getdns_return_t extract_addrtuple(struct gaih_addrtuple **result_addrtuple, response_bundle *response, 
		char *intern_buffer, size_t buflen, uint32_t *respstatus)
{
	if(!response)
	{
		log_warning("extract_addrtuple():error parsing response.");
		return GETDNS_RETURN_GENERIC_ERROR;
	}else if(response->ipv4_count + response->ipv6_count <= 0)
	{
		log_info("extract_addrtuple(): No answers: %s.", getdns_get_errorstr_by_id(response->respstatus));
		*respstatus = GETDNS_RESPSTATUS_NO_NAME;
		return GETDNS_RETURN_GOOD;
	}
	size_t rec_count = 0, num_answers = 0;
	size_t idx, min_space, cname_len;
	num_answers = response->ipv4_count + response->ipv6_count;
    char *canon_name = response->cname;
    cname_len = strlen(canon_name) + 2;
    min_space = cname_len + (sizeof(struct gaih_addrtuple) * num_answers);
    if( buflen < min_space )
    {
        log_critical("GETDNS: Buffer too small: %zd\n", buflen);
        return GETDNS_RETURN_MEMORY_ERROR;
    }
    struct gaih_addrtuple *gaih_ptr = *result_addrtuple;
    /*Fill in hostname*/
    char *hname;
    hname = intern_buffer;
    memcpy(hname, canon_name, cname_len-2);
    memset(hname + cname_len-1, 0, sizeof(char));
    idx = cname_len;
    
    if(response->ipv6_count > 0)
    {
    	char **addr_list = malloc(sizeof(char*)*response->ipv6_count);
    	assert(addr_list);
    	int num = parse_addr_list(response->ipv6, addr_list, response->ipv6_count);
		for(rec_count = 0; rec_count < num; ++rec_count)
		{
		    add_addrtuple(addr_list[rec_count], AF_INET6);
		}
		free(addr_list);
    }
    if(response->ipv4_count > 0)
    {
    	char **addr_list = malloc(sizeof(char*)*response->ipv4_count);
    	assert(addr_list);
    	int num = parse_addr_list(response->ipv4, addr_list, response->ipv4_count);
		int addr_idx;
		for(addr_idx = 0; addr_idx < num; ++addr_idx)
		{
		    add_addrtuple(addr_list[addr_idx], AF_INET);
		    rec_count++;
		}
		free(addr_list);
    }
    assert(idx <= min_space); /*Check if we didn't write past the intended space...*/
    *respstatus = rec_count > 0 ? GETDNS_RESPSTATUS_GOOD : GETDNS_RESPSTATUS_NO_NAME;
	return GETDNS_RETURN_GOOD;
}
Beispiel #2
0
void callback(getdns_context *context, getdns_callback_type_t callback_type,
    getdns_dict *response, void *userarg, getdns_transaction_t trans_id)
{
	char *response_str;

	if (callback_type == GETDNS_CALLBACK_COMPLETE) {
		/* This is a callback with data */;
		if (!quiet && (response_str = json ?
		    getdns_print_json_dict(response, json == 1)
		  : getdns_pretty_print_dict(response))) {

			fprintf(stdout, "ASYNC response:\n%s\n", response_str);
			validate_chain(response);
			free(response_str);
		}
		fprintf(stdout,
			"Result:      The callback with ID %llu  was successfull.\n",
			(unsigned long long)trans_id);

	} else if (callback_type == GETDNS_CALLBACK_CANCEL)
		fprintf(stderr,
			"Result:      The callback with ID %llu was cancelled. Exiting.\n",
			(unsigned long long)trans_id);
	else {
		fprintf(stderr,
			"Result:      The callback got a callback_type of %d. Exiting.\n",
			callback_type);
		fprintf(stderr,
			"Error :      '%s'\n",
			getdns_get_errorstr_by_id(callback_type));
	}
	getdns_dict_destroy(response);
	response = NULL;
}
Beispiel #3
0
getdns_return_t
getdns_strerror(getdns_return_t err, char *buf, size_t buflen)
{
	const char *err_str = getdns_get_errorstr_by_id(err);

	(void) snprintf(buf, buflen, "%s",
	    err_str ? err_str : "/* <unknown getdns value> */");

	return GETDNS_RETURN_GOOD;
}				/* getdns_strerror */
Beispiel #4
0
getdns_return_t
getdns_strerror(getdns_return_t err, char *buf, size_t buflen)
{
    getdns_return_t retval = GETDNS_RETURN_GOOD;

    const char *err_str = getdns_get_errorstr_by_id(err);
    if (!err_str) {
        return GETDNS_RETURN_GENERIC_ERROR;
    }

    snprintf(buf, buflen, "%s", err_str);

    return retval;
}				/* getdns_strerror */
Beispiel #5
0
int main()
{
	getdns_return_t r;
	getdns_context *ctx = NULL;

	if ((r = getdns_context_create(&ctx, 1)))
		fprintf(stderr, "Could not create context");

	if (ctx)
		getdns_context_destroy(ctx);

	if (r) {
		fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r));
		exit(EXIT_FAILURE);
	}
	exit(EXIT_SUCCESS);
}
Beispiel #6
0
int main()
{
	getdns_return_t r = GETDNS_RETURN_MEMORY_ERROR;
	getdns_dict    *dict = NULL;
	unsigned char   bladiebla_str[] = "bla die bla";
	getdns_bindata  bladiebla = { sizeof(bladiebla_str), bladiebla_str };

	if (!(dict = getdns_dict_create()))
		fprintf(stderr, "Could not create dict");

	else if ((r = getdns_dict_set_int(dict, "/bla/bloe/blie", 53280))
	     ||  (r = getdns_dict_set_int(dict, "/bla/hola", 53281))
	     ||  (r = getdns_dict_set_int(dict, "/bla/cola/-", 1))
	     ||  (r = getdns_dict_set_int(dict, "/bla/cola/-", 2))
	     ||  (r = getdns_dict_set_int(dict, "/bla/cola/-/drie", 3))
	     ||  (r = getdns_dict_set_int(dict, "/bla/cola/-", 4))
	     ||  (r = getdns_dict_set_int(dict, "/bla/cola/1", 5))
	     ||  (r = getdns_dict_set_int(dict, "/bla/cola/2/zes", 6))
	     ||  (r = getdns_dict_set_bindata(dict, "/die/bla", &bladiebla))
	     )
		fprintf(stderr, "Error setting dict data");
	else {
		char *dict_str = getdns_pretty_print_dict(dict);

		if (!dict_str) {
			fprintf(stderr, "Could not convert dict to string");
			r = GETDNS_RETURN_MEMORY_ERROR;
		} else {
			printf("%s\n", dict_str);
			free(dict_str);
		}
	}
	if (r)
		fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r));

	if (dict)
		getdns_dict_destroy(dict);

	if (r)
		exit(EXIT_FAILURE);

	exit(EXIT_SUCCESS);
}
Beispiel #7
0
/*
* This function combines both getaddrinfo() and getnameinfo(), so in short, everything the module does!
* This was decided for simplicity purposes since this is just a wrapper around getdns which does all the work.
*/
getdns_return_t getdns_gethostinfo(const char *name, int af, struct addr_param *result_ptr, 
        char *intern_buffer, size_t buflen, int32_t *ttlp, char **canonp, uint32_t *respstatus, uint32_t *dnssec_status)
{
    getdns_return_t return_code; 
    if(!intern_buffer || buflen < sizeof(char) || (!result_ptr))
    {
        log_critical("getdns_gethostinfo: Memory error...");
        return GETDNS_RETURN_MEMORY_ERROR;
    }
    *respstatus = GETDNS_RESPSTATUS_NO_NAME;
    if( (af != AF_INET) && (af != AF_INET6) && (af != AF_UNSPEC) )
    {
        log_warning("getdns_gethostinfo: Address family not supported: %d .", af);
        return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
    }
    memset(intern_buffer, 0, buflen);
    UNUSED_PARAM(ttlp);
	struct callback_fn_arg arg = {.result_ptr=result_ptr, .af=af, .buffer=intern_buffer, .buflen=buflen,
 			.respstatus=respstatus, .dnssec_status=dnssec_status
 	};
	if((return_code = resolve(name, &arg)) != GETDNS_RETURN_GOOD)
	{
		log_info("getdns_gethostinfo(<%s>): Failed parsing response: ERROR < %d >\n", name, return_code);
	}
	 /*
	This section is not complete:
	TODO:
	1. Do all the getdns data structures need to be cleaned up, or does destroying the top-level node suffice? 
	*Let's valgrind it and see, maybe?!
	*/
	if(canonp && *respstatus == GETDNS_RESPSTATUS_GOOD)
	{
		*canonp = result_ptr->addr_entry.p_hostent->h_name;
	}
	log_debug("Query(%s) => < %d > - DNSSEC STATUS: {%s}\n", name, *respstatus, getdns_get_errorstr_by_id(*dnssec_status));
    return return_code;
}
Beispiel #8
0
int
main(int argc, char **argv)
{
	getdns_dict *response = NULL;
	char *response_str;
	getdns_return_t r;
	getdns_dict *address = NULL;
	FILE *fp = NULL;

	name = the_root;
	if ((r = getdns_context_create(&context, 1))) {
		fprintf(stderr, "Create context failed: %d\n", r);
		return r;
	}
	extensions = getdns_dict_create();
	if (! extensions) {
		fprintf(stderr, "Could not create extensions dict\n");
		r = GETDNS_RETURN_MEMORY_ERROR;
		goto done_destroy_context;
	}
	if ((r = parse_args(argc, argv)))
		goto done_destroy_context;

	if (query_file) {
		fp = fopen(query_file, "rt");
		if (fp == NULL) {
			fprintf(stderr, "Could not open query file: %s\n", query_file);
			goto done_destroy_context;
		}
	}

	/* Make the call */
	do {
		char line[1024], *token, *linev[256];
		int linec;
		if (interactive) {
			if (!query_file) {
				fprintf(stdout, "> ");
				if (!fgets(line, 1024, stdin) || !*line)
					break;
			} else {
				if (!fgets(line, 1024, fp) || !*line) {
					fprintf(stdout,"End of file.");
					break;
				}
				fprintf(stdout,"Found query: %s", line);
			}

			linev[0] = argv[0];
			linec = 1;
			if ( ! (token = strtok(line, " \t\f\n\r")))
				continue;
			if (*token == '#') {
				fprintf(stdout,"Result:      Skipping comment\n");
					continue;
			}
			do linev[linec++] = token;
			while (linec < 256 &&
			    (token = strtok(NULL, " \t\f\n\r")));
			if ((r = parse_args(linec, linev))) {
				if (r == CONTINUE || r == CONTINUE_ERROR)
					continue;
				else
					goto done_destroy_context;
			}

		}
		if (calltype == HOSTNAME &&
		    !(address = ipaddr_dict(context, name))) {
			fprintf(stderr, "Could not convert \"%s\" "
			                "to an IP address", name);
			continue;
		}
		if (async) {
			switch (calltype) {
			case GENERAL:
				r = getdns_general(context, name, request_type,
				    extensions, &response, NULL, callback);
				break;
			case ADDRESS:
				r = getdns_address(context, name,
				    extensions, &response, NULL, callback);
				break;
			case HOSTNAME:
				r = getdns_hostname(context, address,
				    extensions, &response, NULL, callback);
				break;
			case SERVICE:
				r = getdns_service(context, name,
				    extensions, &response, NULL, callback);
				break;
			default:
				r = GETDNS_RETURN_GENERIC_ERROR;
				break;
			}
			if (r)
				goto done_destroy_extensions;
			if (!batch_mode) 
				getdns_context_run(context);
		} else {
			switch (calltype) {
			case GENERAL:
				r = getdns_general_sync(context, name,
				    request_type, extensions, &response);
				break;
			case ADDRESS:
				r = getdns_address_sync(context, name,
				    extensions, &response);
				break;
			case HOSTNAME:
				r = getdns_hostname_sync(context, address,
				    extensions, &response);
				break;
			case SERVICE:
				r = getdns_service_sync(context, name,
				    extensions, &response);
				break;
			default:
				r = GETDNS_RETURN_GENERIC_ERROR;
				break;
			}
			if (response && !quiet) {
				if ((response_str = json ?
				    getdns_print_json_dict(response, json == 1)
				  : getdns_pretty_print_dict(response))) {

					fprintf( stdout, "SYNC response:\n%s\n"
					       , response_str);
					validate_chain(response);
					free(response_str);
				} else {
					r = GETDNS_RETURN_MEMORY_ERROR;
					fprintf( stderr
					       , "Could not print response\n");
				}
			}
			if (r == GETDNS_RETURN_GOOD) {
				uint32_t status;
				getdns_dict_get_int(response, "status", &status);
				fprintf(stdout, "Response code was: GOOD. Status was: %s\n", 
				         getdns_get_errorstr_by_id(status));
			} else
				fprintf(stderr, "An error occurred: %d '%s'\n", r,
				         getdns_get_errorstr_by_id(r));
		}
	} while (interactive);

	if (batch_mode) 
		getdns_context_run(context);

	/* Clean up */
done_destroy_extensions:
	getdns_dict_destroy(extensions);
done_destroy_context:
	if (response) getdns_dict_destroy(response);
	getdns_context_destroy(context);

	if (fp)
		fclose(fp);

	if (r == CONTINUE)
		return 0;
	else if (r == CONTINUE_ERROR)
		return 1;
	fprintf(stdout, "\nAll done.\n");
	return r;
}
Beispiel #9
0
int
main(int argc, char *argv[])
{
    char *name = "getdnsapi.net";
    getdns_context *context;
    getdns_return_t ret;
    getdns_dict *extensions;
    getdns_dict *response;
    uint32_t status;
    uint32_t dnssec_status;
    uint32_t type;
    getdns_list *replies_tree;
    size_t nanswers;
    int  i;
    char element[MAXELEM];

    if (argc > 1)
        name = argv[1];

    if ((ret = getdns_context_create(&context, 1)) != GETDNS_RETURN_GOOD)  {
        fprintf(stderr, "getdns_context_create: %s\n",
		    getdns_get_errorstr_by_id(ret));
        return 1;
    }

    extensions = getdns_dict_create();
    if ((ret = getdns_dict_set_int(extensions, "/dnssec_return_status",
                                   GETDNS_EXTENSION_TRUE)) != GETDNS_RETURN_GOOD)  {
      	fprintf(stderr, "getdns_dict_set_int(dnssec_return_status): %s\n",
                getdns_get_errorstr_by_id(ret));
        return 1;
    }
    if ((ret = getdns_address_sync(context, name, extensions, &response)) !=
        GETDNS_RETURN_GOOD)  {
	      fprintf(stderr, "getdns_address_sync: %s\n",
                getdns_get_errorstr_by_id(ret));
        return 1;
    }

    (void)getdns_dict_get_int(response, "status", &status);
    if (status != GETDNS_RESPSTATUS_GOOD)  {
        printf("Bad status: ");
        switch (status) {
        case GETDNS_RESPSTATUS_NO_NAME:
            printf("GETDNS_RESPSTATUS_NO_NAME\n");
            break;
        case GETDNS_RESPSTATUS_ALL_TIMEOUT:
            printf("GETDNS_RESPSTATUS_ALL_TIMEOUT\n");
            break;
        default:
            break;
        }
    }

    if ((ret = getdns_dict_get_list(response, "/replies_tree", &replies_tree)) !=
        GETDNS_RETURN_GOOD)  {
        fprintf(stderr, "getdns_dict_get_list(replies_tree): %s\n",
		getdns_get_errorstr_by_id(ret));
        return 1;
    }

    (void)getdns_list_get_length(replies_tree, &nanswers);
    printf("%d answers\n", (int)nanswers);

    for ( i = 0 ; i < (int)nanswers ; i++ )  {
        snprintf(element, MAXELEM, "/replies_tree/%d/dnssec_status", i);
        (void)getdns_dict_get_int(response, element, &dnssec_status);
	      snprintf(element, MAXELEM, "/replies_tree/%d/answer/0/type", i);
        (void)getdns_dict_get_int(response, element, &type);
        printf("dnssec_status for %s record: %s\n", address_type_to_string(type),
               dnssec_status_to_string(dnssec_status));
      }


    /*
     * handy debugging tool - uncomment if wanted
     */

    /* printf("%s\n", getdns_pretty_print_dict(response)); */

    return 0;

}