#include "asterisk.h"
#include "asterisk/network.h"
#include <arpa/nameser.h>
#include <resolv.h>
#include "asterisk/channel.h"
#include "asterisk/dns.h"
#include "asterisk/endian.h"
Go to the source code of this file.
Data Structures | |
struct | dn_answer |
struct | dns_HEADER |
Defines | |
#define | MAX_SIZE 4096 |
Functions | |
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) |
Definition in file dns.c.
#define MAX_SIZE 4096 |
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 259 of file dns.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, dns_parse_answer(), LOG_WARNING, and MAX_SIZE.
Referenced by ast_get_enum(), ast_get_srv(), ast_srv_lookup(), blr_ebl(), and blr_txt().
00262 { 00263 #ifdef HAVE_RES_NINIT 00264 struct __res_state dnsstate; 00265 #endif 00266 unsigned char answer[MAX_SIZE]; 00267 int res, ret = -1; 00268 00269 #ifdef HAVE_RES_NINIT 00270 memset(&dnsstate, 0, sizeof(dnsstate)); 00271 res_ninit(&dnsstate); 00272 res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer)); 00273 #else 00274 ast_mutex_lock(&res_lock); 00275 res_init(); 00276 res = res_search(dname, class, type, answer, sizeof(answer)); 00277 #endif 00278 if (res > 0) { 00279 if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) { 00280 ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname); 00281 ret = -1; 00282 } else if (res == 0) { 00283 ast_debug(1, "No matches found in DNS for %s\n", dname); 00284 ret = 0; 00285 } else 00286 ret = 1; 00287 } 00288 #ifdef HAVE_RES_NINIT 00289 #ifdef HAVE_RES_NDESTROY 00290 res_ndestroy(&dnsstate); 00291 #else 00292 res_nclose(&dnsstate); 00293 #endif 00294 #else 00295 #ifdef HAVE_RES_CLOSE 00296 res_close(); 00297 #endif 00298 ast_mutex_unlock(&res_lock); 00299 #endif 00300 00301 return ret; 00302 }
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 189 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().
00192 { 00193 unsigned char *fullanswer = answer; 00194 struct dn_answer *ans; 00195 dns_HEADER *h; 00196 int ret = 0; 00197 int res; 00198 int x; 00199 00200 h = (dns_HEADER *)answer; 00201 answer += sizeof(dns_HEADER); 00202 len -= sizeof(dns_HEADER); 00203 00204 for (x = 0; x < ntohs(h->qdcount); x++) { 00205 if ((res = skip_name(answer, len)) < 0) { 00206 ast_log(LOG_WARNING, "Couldn't skip over name\n"); 00207 return -1; 00208 } 00209 answer += res + 4; /* Skip name and QCODE / QCLASS */ 00210 len -= res + 4; 00211 if (len < 0) { 00212 ast_log(LOG_WARNING, "Strange query size\n"); 00213 return -1; 00214 } 00215 } 00216 00217 for (x = 0; x < ntohs(h->ancount); x++) { 00218 if ((res = skip_name(answer, len)) < 0) { 00219 ast_log(LOG_WARNING, "Failed skipping name\n"); 00220 return -1; 00221 } 00222 answer += res; 00223 len -= res; 00224 ans = (struct dn_answer *)answer; 00225 answer += sizeof(struct dn_answer); 00226 len -= sizeof(struct dn_answer); 00227 if (len < 0) { 00228 ast_log(LOG_WARNING, "Strange result size\n"); 00229 return -1; 00230 } 00231 if (len < 0) { 00232 ast_log(LOG_WARNING, "Length exceeds frame\n"); 00233 return -1; 00234 } 00235 00236 if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) { 00237 if (callback) { 00238 if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) { 00239 ast_log(LOG_WARNING, "Failed to parse result\n"); 00240 return -1; 00241 } 00242 ret = 1; 00243 } 00244 } 00245 answer += ntohs(ans->size); 00246 len -= ntohs(ans->size); 00247 } 00248 return ret; 00249 }
static int skip_name | ( | unsigned char * | s, | |
int | len | |||
) | [static] |
Definition at line 165 of file dns.c.
Referenced by dns_parse_answer().
00166 { 00167 int x = 0; 00168 00169 while (x < len) { 00170 if (*s == '\0') { 00171 s++; 00172 x++; 00173 break; 00174 } 00175 if ((*s & 0xc0) == 0xc0) { 00176 s += 2; 00177 x += 2; 00178 break; 00179 } 00180 x += *s + 1; 00181 s += *s + 1; 00182 } 00183 if (x >= len) 00184 return -1; 00185 return x; 00186 }