39 #include <arpa/nameser.h> 50 #if __BYTE_ORDER == __PDP_ENDIAN 51 #define DETERMINED_BYTE_ORDER __LITTLE_ENDIAN 54 #if __BYTE_ORDER == __BIG_ENDIAN 55 #define DETERMINED_BYTE_ORDER __BIG_ENDIAN 57 #if __BYTE_ORDER == __LITTLE_ENDIAN 58 #define DETERMINED_BYTE_ORDER __LITTLE_ENDIAN 61 #ifndef HAVE_RES_NINIT 126 #if DETERMINED_BYTE_ORDER == __BIG_ENDIAN 140 #if DETERMINED_BYTE_ORDER == __LITTLE_ENDIAN 163 unsigned short class;
166 } __attribute__((__packed__));
190 if ((*s & 0xc0) == 0xc0) {
225 if (dns_response ==
NULL || field_size < 0 || remaining_len < field_size) {
229 *dns_response += field_size;
230 remaining_len -= field_size;
232 return remaining_len;
235 #ifndef HAVE_RES_NINIT 250 static int dns_search_res(
const char *dname,
int rr_class,
int rr_type,
251 unsigned char *dns_response,
int dns_response_len)
258 ret = res_search(dname,
264 #ifdef HAVE_RES_CLOSE 288 unsigned char *dns_response,
int dns_response_len)
292 struct __res_state dns_state;
294 memset(&dns_state, 0,
sizeof(dns_state));
295 res_ninit(&dns_state);
296 ret = res_nsearch(&dns_state,
303 #ifdef HAVE_RES_NDESTROY 304 res_ndestroy(&dns_state);
306 res_nclose(&dns_state);
332 int (*callback)(
void *context,
unsigned char *answer,
int len,
unsigned char *fullanswer))
334 unsigned char *fullanswer =
answer;
345 for (x = 0; x < ntohs(h->
qdcount); x++) {
346 if ((res =
skip_name(answer, len)) < 0) {
358 for (x = 0; x < ntohs(h->
ancount); x++) {
359 if ((res =
skip_name(answer, len)) < 0) {
373 if (ntohs(ans->
class) ==
class && ntohs(ans->
rtype) == type) {
375 if ((res = callback(context, answer, ntohs(ans->
size), fullanswer)) < 0) {
382 answer += ntohs(ans->
size);
383 len -= ntohs(ans->
size);
409 static int dns_parse_answer_ex(
void *context,
int rr_class,
int rr_type,
unsigned char *answer,
int answer_len,
410 int (*response_handler)(
void *context,
unsigned char *dns_response,
int dns_response_len,
int rcode),
411 int (*record_handler)(
void *context,
unsigned char *record,
int record_len,
int ttl))
413 unsigned char *dns_response =
answer;
417 int res, x, pos, dns_response_len, ret;
419 dns_response_len = answer_len;
423 response_handler(context, dns_response, dns_response_len, ntohs(dns_header->rcode));
426 if (answer_len == 0) {
437 for (x = 0; x < ntohs(dns_header->
qdcount); x++) {
438 if ((res =
skip_name(answer, pos)) < 0) {
450 for (x = 0; x < ntohs(dns_header->
ancount); x++) {
451 if ((res =
skip_name(answer, pos)) < 0) {
472 if (ntohs(ans->
class) == rr_class && ntohs(ans->
rtype) == rr_type) {
474 record_handler(context, answer, ntohs(ans->
size), ntohl(ans->
ttl));
494 const char *dname,
int class,
int type,
495 int (*callback)(
void *context,
unsigned char *answer,
int len,
unsigned char *fullanswer))
497 #ifdef HAVE_RES_NINIT 498 struct __res_state dnsstate;
503 #ifdef HAVE_RES_NINIT 504 memset(&dnsstate, 0,
sizeof(dnsstate));
505 res_ninit(&dnsstate);
506 res = res_nsearch(&dnsstate, dname,
class, type, answer,
sizeof(answer));
510 res = res_search(dname,
class, type, answer,
sizeof(answer));
513 if ((res =
dns_parse_answer(context,
class, type, answer, res, callback)) < 0) {
516 }
else if (res == 0) {
517 ast_debug(1,
"No matches found in DNS for %s\n", dname);
522 #ifdef HAVE_RES_NINIT 523 #ifdef HAVE_RES_NDESTROY 524 res_ndestroy(&dnsstate);
526 res_nclose(&dnsstate);
529 #ifdef HAVE_RES_CLOSE 539 int (*response_handler)(
void *context,
unsigned char *dns_response,
int dns_response_len,
int rcode),
540 int (*record_handler)(
void *context,
unsigned char *record,
int record_len,
int ttl))
542 int ret, dns_response_len;
543 unsigned char dns_response[
MAX_SIZE];
554 sizeof(dns_response));
556 if (dns_response_len < 0) {
557 ast_debug(1,
"DNS search failed for %s\n", dname);
558 response_handler(context, (
unsigned char *)
"", 0, NXDOMAIN);
577 ast_debug(1,
"DNS search yielded no results for %s\n", dname);
585 #ifdef HAVE_RES_NINIT 586 struct __res_state dnsstate;
588 struct __res_state *
state;
597 #ifdef HAVE_RES_NINIT 598 memset(&dnsstate, 0,
sizeof(dnsstate));
599 res_ninit(&dnsstate);
607 for (i = 0; i < state->nscount; i++) {
611 #ifdef HAVE_RES_NINIT 612 #ifdef HAVE_RES_NDESTROY 613 res_ndestroy(&dnsstate);
615 res_nclose(&dnsstate);
618 #ifdef HAVE_RES_CLOSE
enum sip_cc_notify_state state
Asterisk main include file. File version handling, generic pbx functions.
static int dns_parse_answer_ex(void *context, int rr_class, int rr_type, unsigned char *answer, int answer_len, int(*response_handler)(void *context, unsigned char *dns_response, int dns_response_len, int rcode), int(*record_handler)(void *context, unsigned char *record, int record_len, int ttl))
Extended version of the DNS Parsing function.
#define ast_mutex_lock(a)
enum ast_dns_search_result ast_search_dns_ex(void *context, const char *dname, int rr_class, int rr_type, int(*response_handler)(void *context, unsigned char *dns_response, int dns_response_len, int rcode), int(*record_handler)(void *context, unsigned char *record, int record_len, int ttl))
Extended version of the DNS search function.
static int dns_advance_field(unsigned char **dns_response, int remaining_len, int field_size)
Advances the position of the DNS response pointer by the size of the current field.
#define ast_debug(level,...)
Log a DEBUG message.
static int dns_search_res(const char *dname, int rr_class, int rr_type, unsigned char *dns_response, int dns_response_len)
Handles the DNS search if the system has RES_NINIT.
General Asterisk PBX channel definitions.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
ast_dns_search_result
DNS search return values.
Asterisk architecture endianess compatibility definitions.
static int answer(void *data)
Wrapper for network related headers, masking differences between various operating systems...
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
static int skip_name(unsigned char *s, int len)
Tries to find the position of the next field in the DNS response.
struct ao2_container * ast_dns_get_nameservers(void)
Retrieve the configured nameservers of the system.
#define MAX_SIZE
The maximum size permitted for the answer from the DNS server.
static char context[AST_MAX_CONTEXT]
int ast_search_dns(void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Lookup record in DNS.
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
#define AST_MUTEX_DEFINE_STATIC(mutex)
DNS support for Asterisk.
static int dns_parse_answer(void *context, int class, int type, unsigned char *answer, int len, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Parse DNS lookup result, call callback.
#define ast_mutex_unlock(a)