00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 159851 $")
00035
00036 #include "asterisk/network.h"
00037 #include <arpa/nameser.h>
00038 #include <resolv.h>
00039
00040 #include "asterisk/channel.h"
00041 #include "asterisk/dns.h"
00042 #include "asterisk/endian.h"
00043
00044 #define MAX_SIZE 4096
00045
00046 #ifdef __PDP_ENDIAN
00047 #if __BYTE_ORDER == __PDP_ENDIAN
00048 #define DETERMINED_BYTE_ORDER __LITTLE_ENDIAN
00049 #endif
00050 #endif
00051 #if __BYTE_ORDER == __BIG_ENDIAN
00052 #define DETERMINED_BYTE_ORDER __BIG_ENDIAN
00053 #endif
00054 #if __BYTE_ORDER == __LITTLE_ENDIAN
00055 #define DETERMINED_BYTE_ORDER __LITTLE_ENDIAN
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 typedef struct {
00118 unsigned id:16;
00119 #if DETERMINED_BYTE_ORDER == __BIG_ENDIAN
00120
00121 unsigned qr:1;
00122 unsigned opcode:4;
00123 unsigned aa:1;
00124 unsigned tc:1;
00125 unsigned rd:1;
00126
00127 unsigned ra:1;
00128 unsigned unused:1;
00129 unsigned ad:1;
00130 unsigned cd:1;
00131 unsigned rcode:4;
00132 #endif
00133 #if DETERMINED_BYTE_ORDER == __LITTLE_ENDIAN
00134
00135 unsigned rd:1;
00136 unsigned tc:1;
00137 unsigned aa:1;
00138 unsigned opcode:4;
00139 unsigned qr:1;
00140
00141 unsigned rcode:4;
00142 unsigned cd:1;
00143 unsigned ad:1;
00144 unsigned unused:1;
00145 unsigned ra:1;
00146 #endif
00147
00148 unsigned qdcount:16;
00149 unsigned ancount:16;
00150 unsigned nscount:16;
00151 unsigned arcount:16;
00152 } dns_HEADER;
00153
00154 struct dn_answer {
00155 unsigned short rtype;
00156 unsigned short class;
00157 unsigned int ttl;
00158 unsigned short size;
00159 } __attribute__((__packed__));
00160
00161 static int skip_name(unsigned char *s, int len)
00162 {
00163 int x = 0;
00164
00165 while (x < len) {
00166 if (*s == '\0') {
00167 s++;
00168 x++;
00169 break;
00170 }
00171 if ((*s & 0xc0) == 0xc0) {
00172 s += 2;
00173 x += 2;
00174 break;
00175 }
00176 x += *s + 1;
00177 s += *s + 1;
00178 }
00179 if (x >= len)
00180 return -1;
00181 return x;
00182 }
00183
00184
00185 static int dns_parse_answer(void *context,
00186 int class, int type, unsigned char *answer, int len,
00187 int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
00188 {
00189 unsigned char *fullanswer = answer;
00190 struct dn_answer *ans;
00191 dns_HEADER *h;
00192 int ret = 0;
00193 int res;
00194 int x;
00195
00196 h = (dns_HEADER *)answer;
00197 answer += sizeof(dns_HEADER);
00198 len -= sizeof(dns_HEADER);
00199
00200 for (x = 0; x < ntohs(h->qdcount); x++) {
00201 if ((res = skip_name(answer, len)) < 0) {
00202 ast_log(LOG_WARNING, "Couldn't skip over name\n");
00203 return -1;
00204 }
00205 answer += res + 4;
00206 len -= res + 4;
00207 if (len < 0) {
00208 ast_log(LOG_WARNING, "Strange query size\n");
00209 return -1;
00210 }
00211 }
00212
00213 for (x = 0; x < ntohs(h->ancount); x++) {
00214 if ((res = skip_name(answer, len)) < 0) {
00215 ast_log(LOG_WARNING, "Failed skipping name\n");
00216 return -1;
00217 }
00218 answer += res;
00219 len -= res;
00220 ans = (struct dn_answer *)answer;
00221 answer += sizeof(struct dn_answer);
00222 len -= sizeof(struct dn_answer);
00223 if (len < 0) {
00224 ast_log(LOG_WARNING, "Strange result size\n");
00225 return -1;
00226 }
00227 if (len < 0) {
00228 ast_log(LOG_WARNING, "Length exceeds frame\n");
00229 return -1;
00230 }
00231
00232 if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
00233 if (callback) {
00234 if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
00235 ast_log(LOG_WARNING, "Failed to parse result\n");
00236 return -1;
00237 }
00238 ret = 1;
00239 }
00240 }
00241 answer += ntohs(ans->size);
00242 len -= ntohs(ans->size);
00243 }
00244 return ret;
00245 }
00246
00247 #ifndef HAVE_RES_NINIT
00248 AST_MUTEX_DEFINE_STATIC(res_lock);
00249 #endif
00250
00251
00252
00253
00254
00255 int ast_search_dns(void *context,
00256 const char *dname, int class, int type,
00257 int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
00258 {
00259 #ifdef HAVE_RES_NINIT
00260 struct __res_state dnsstate;
00261 #endif
00262 unsigned char answer[MAX_SIZE];
00263 int res, ret = -1;
00264
00265 #ifdef HAVE_RES_NINIT
00266 memset(&dnsstate, 0, sizeof(dnsstate));
00267 res_ninit(&dnsstate);
00268 res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer));
00269 #else
00270 ast_mutex_lock(&res_lock);
00271 res_init();
00272 res = res_search(dname, class, type, answer, sizeof(answer));
00273 #endif
00274 if (res > 0) {
00275 if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) {
00276 ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname);
00277 ret = -1;
00278 } else if (res == 0) {
00279 ast_debug(1, "No matches found in DNS for %s\n", dname);
00280 ret = 0;
00281 } else
00282 ret = 1;
00283 }
00284 #ifdef HAVE_RES_NINIT
00285 #ifdef HAVE_RES_NDESTROY
00286 res_ndestroy(&dnsstate);
00287 #else
00288 res_nclose(&dnsstate);
00289 #endif
00290 #else
00291 #ifndef __APPLE__
00292 res_close();
00293 #endif
00294 ast_mutex_unlock(&res_lock);
00295 #endif
00296
00297 return ret;
00298 }