#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <unistd.h>
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/dns.h"
#include "asterisk/endian.h"
Include dependency graph for dns.c:
Go to the source code of this file.
Data Structures | |
struct | dn_answer |
struct | dns_HEADER |
Defines | |
#define | MAX_SIZE 4096 |
Functions | |
AST_MUTEX_DEFINE_STATIC (res_lock) | |
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)) |
Perform DNS lookup (used by DNS, enum and SRV lookups). | |
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. | |
static int | skip_name (unsigned char *s, int len) |
Variables | |
dn_answer | __packed__ |
Definition in file dns.c.
#define MAX_SIZE 4096 |
AST_MUTEX_DEFINE_STATIC | ( | res_lock | ) |
int ast_search_dns | ( | void * | context, | |
const char * | dname, | |||
int | class, | |||
int | type, | |||
int(*)(void *context, unsigned char *answer, int len, unsigned char *fullanswer) | callback | |||
) |
Perform DNS lookup (used by DNS, enum and SRV lookups).
Definition at line 188 of file dns.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), dns_parse_answer(), LOG_DEBUG, LOG_WARNING, and MAX_SIZE.
Referenced by ast_get_enum(), ast_get_srv(), and ast_get_txt().
00191 { 00192 #if HAVE_RES_NINIT 00193 struct __res_state dnsstate; 00194 #endif 00195 unsigned char answer[MAX_SIZE]; 00196 int res, ret = -1; 00197 00198 #if HAVE_RES_NINIT 00199 res_ninit(&dnsstate); 00200 res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer)); 00201 #else 00202 ast_mutex_lock(&res_lock); 00203 res_init(); 00204 res = res_search(dname, class, type, answer, sizeof(answer)); 00205 #endif 00206 if (res > 0) { 00207 if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) { 00208 ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname); 00209 ret = -1; 00210 } 00211 else if (ret == 0) { 00212 ast_log(LOG_DEBUG, "No matches found in DNS for %s\n", dname); 00213 ret = 0; 00214 } 00215 else 00216 ret = 1; 00217 } 00218 #if HAVE_RES_NINIT 00219 res_nclose(&dnsstate); 00220 #else 00221 #ifndef __APPLE__ 00222 res_close(); 00223 #endif 00224 ast_mutex_unlock(&res_lock); 00225 #endif 00226 00227 return ret; 00228 }
static int dns_parse_answer | ( | void * | context, | |
int | class, | |||
int | type, | |||
unsigned char * | answer, | |||
int | len, | |||
int(*)(void *context, unsigned char *answer, int len, unsigned char *fullanswer) | callback | |||
) | [static] |
Parse DNS lookup result, call callback.
Definition at line 118 of file dns.c.
References dns_HEADER::ancount, ast_log(), dn_answer::class, LOG_WARNING, dns_HEADER::qdcount, dn_answer::rtype, dn_answer::size, and skip_name().
Referenced by ast_search_dns().
00121 { 00122 unsigned char *fullanswer = answer; 00123 struct dn_answer *ans; 00124 dns_HEADER *h; 00125 int res; 00126 int x; 00127 00128 h = (dns_HEADER *)answer; 00129 answer += sizeof(dns_HEADER); 00130 len -= sizeof(dns_HEADER); 00131 00132 for (x = 0; x < ntohs(h->qdcount); x++) { 00133 if ((res = skip_name(answer, len)) < 0) { 00134 ast_log(LOG_WARNING, "Couldn't skip over name\n"); 00135 return -1; 00136 } 00137 answer += res + 4; /* Skip name and QCODE / QCLASS */ 00138 len -= res + 4; 00139 if (len < 0) { 00140 ast_log(LOG_WARNING, "Strange query size\n"); 00141 return -1; 00142 } 00143 } 00144 00145 for (x = 0; x < ntohs(h->ancount); x++) { 00146 if ((res = skip_name(answer, len)) < 0) { 00147 ast_log(LOG_WARNING, "Failed skipping name\n"); 00148 return -1; 00149 } 00150 answer += res; 00151 len -= res; 00152 ans = (struct dn_answer *)answer; 00153 answer += sizeof(struct dn_answer); 00154 len -= sizeof(struct dn_answer); 00155 if (len < 0) { 00156 ast_log(LOG_WARNING, "Strange result size\n"); 00157 return -1; 00158 } 00159 if (len < 0) { 00160 ast_log(LOG_WARNING, "Length exceeds frame\n"); 00161 return -1; 00162 } 00163 00164 if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) { 00165 if (callback) { 00166 if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) { 00167 ast_log(LOG_WARNING, "Failed to parse result\n"); 00168 return -1; 00169 } 00170 if (res > 0) 00171 return 1; 00172 } 00173 } 00174 answer += ntohs(ans->size); 00175 len -= ntohs(ans->size); 00176 } 00177 return 0; 00178 }
static int skip_name | ( | unsigned char * | s, | |
int | len | |||
) | [static] |
Definition at line 94 of file dns.c.
Referenced by dns_parse_answer().
00095 { 00096 int x = 0; 00097 00098 while (x < len) { 00099 if (*s == '\0') { 00100 s++; 00101 x++; 00102 break; 00103 } 00104 if ((*s & 0xc0) == 0xc0) { 00105 s += 2; 00106 x += 2; 00107 break; 00108 } 00109 x += *s + 1; 00110 s += *s + 1; 00111 } 00112 if (x >= len) 00113 return -1; 00114 return x; 00115 }
struct dn_answer __packed__ |