#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <ctype.h>
#include <regex.h>
#include "asterisk/enum.h"
#include "asterisk/dns.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
Go to the source code of this file.
Data Structures | |
struct | enum_search |
Defines | |
#define | ENUMLOOKUP_OPTIONS_COUNT 1 |
#define | TOPLEV "e164.arpa." |
Functions | |
int | ast_enum_init (void) |
int | ast_enum_reload (void) |
int | ast_get_enum (struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char *suffix, char *options, unsigned int record, struct enum_context **argcontext) |
Lookup entry in ENUM. | |
int | ast_get_txt (struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char *txt, int txtlen) |
Lookup DNS TXT record (used by app TXTCIDnum. | |
static int | enum_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer) |
Callback from ENUM lookup function. | |
static struct enum_search * | enum_newtoplev (const char *s) |
Add enum tree to linked list. | |
static unsigned int | parse_ie (char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen) |
Parse NAPTR record information elements. | |
static int | parse_naptr (char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, char *naptrinput) |
Parse DNS NAPTR record used in ENUM ---. | |
static int | private_enum_init (int reload) |
Initialize the ENUM support subsystem. | |
static int | txt_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer) |
Callback for TXT record lookup. | |
Variables | |
static ast_mutex_t | enumlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static int | enumver |
static struct enum_search * | toplevs |
Definition in file enum.c.
#define ENUMLOOKUP_OPTIONS_COUNT 1 |
#define TOPLEV "e164.arpa." |
The IETF Enum standard root, managed by the ITU
Definition at line 76 of file enum.c.
Referenced by private_enum_init().
int ast_enum_init | ( | void | ) |
Definition at line 667 of file enum.c.
References private_enum_init().
Referenced by main().
00668 { 00669 return private_enum_init(0); 00670 }
int ast_enum_reload | ( | void | ) |
Definition at line 672 of file enum.c.
References private_enum_init().
00673 { 00674 return private_enum_init(1); 00675 }
int ast_get_enum | ( | struct ast_channel * | chan, | |
const char * | number, | |||
char * | location, | |||
int | maxloc, | |||
char * | technology, | |||
int | maxtech, | |||
char * | suffix, | |||
char * | options, | |||
unsigned int | record, | |||
struct enum_context ** | argcontext | |||
) |
Lookup entry in ENUM.
chan | Channel | |
number | E164 number with or without the leading + | |
location | Number returned (or SIP uri) | |
maxloc | Max length | |
technology | Technology (from url scheme in response) You can set it to get particular answer RR, if there are many techs in DNS response, example: "sip" If you need any record, then set it to empty string | |
maxtech | Max length | |
suffix | Zone suffix (if is NULL then use enum.conf 'search' variable) | |
options | Options ('c' to count number of NAPTR RR) | |
record | The position of required RR in the answer list | |
argcontext | Argument for caching results into an enum_context pointer (NULL is used for not caching) |
1 | if found | |
0 | if not found | |
-1 | on hangup |
Definition at line 380 of file enum.c.
References ast_autoservice_start(), ast_calloc, ast_copy_string(), ast_debug, ast_free, ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), chan, context, enum_callback(), enumlock, ENUMLOOKUP_OPTIONS_COUNT, errno, enum_context::naptrinput, s, toplevs, and version.
Referenced by enum_query_read(), and function_enum().
00381 { 00382 struct enum_context *context; 00383 char tmp[259 + 512]; 00384 char naptrinput[512]; 00385 int pos = strlen(number) - 1; 00386 int newpos = 0; 00387 int ret = -1; 00388 struct enum_search *s = NULL; 00389 int version = -1; 00390 /* for ISN rewrite */ 00391 char *p1 = NULL; 00392 char *p2 = NULL; 00393 int k = 0; 00394 int i = 0; 00395 int z = 0; 00396 00397 if (!(context = ast_calloc(1, sizeof(*context)))) 00398 return -1; 00399 00400 ast_copy_string(naptrinput, number[0] == 'n' ? number + 1 : number, sizeof(naptrinput)); 00401 00402 context->naptrinput = naptrinput; /* The number */ 00403 context->dst = dst; /* Return string */ 00404 context->dstlen = dstlen; 00405 context->tech = tech; 00406 context->techlen = techlen; 00407 context->options = 0; 00408 context->position = record; 00409 context->naptr_rrs = NULL; 00410 context->naptr_rrs_count = 0; 00411 00412 if (options != NULL) { 00413 if (*options == 'c') { 00414 context->options = ENUMLOOKUP_OPTIONS_COUNT; 00415 context->position = 0; 00416 } 00417 } 00418 00419 ast_debug(1, "ast_get_enum(): n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n", 00420 number, tech, suffix, context->options, context->position); 00421 00422 if (pos > 128) 00423 pos = 128; 00424 00425 /* ISN rewrite */ 00426 p1 = strchr(number, '*'); 00427 00428 if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */ 00429 p1 = NULL; 00430 k = 1; /* strip 'n' from number */ 00431 } 00432 00433 if (p1 != NULL) { 00434 p2 = p1 + 1; 00435 while (p1 > number){ 00436 p1--; 00437 tmp[newpos++] = *p1; 00438 tmp[newpos++] = '.'; 00439 } 00440 if (*p2) { 00441 while (*p2 && newpos < 128){ 00442 tmp[newpos++] = *p2; 00443 p2++; 00444 } 00445 tmp[newpos++] = '.'; 00446 } 00447 00448 } else { 00449 while (pos >= k) { 00450 if (isdigit(number[pos])) { 00451 tmp[newpos++] = number[pos]; 00452 tmp[newpos++] = '.'; 00453 } 00454 pos--; 00455 } 00456 } 00457 00458 if (chan && ast_autoservice_start(chan) < 0) { 00459 ast_free(context); 00460 return -1; 00461 } 00462 00463 if (suffix) { 00464 ast_copy_string(tmp + newpos, suffix, sizeof(tmp) - newpos); 00465 ret = ast_search_dns(context, tmp, C_IN, T_NAPTR, enum_callback); 00466 ast_debug(1, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret); 00467 } else { 00468 ret = -1; /* this is actually dead code since the demise of app_enum.c */ 00469 for (;;) { 00470 ast_mutex_lock(&enumlock); 00471 if (version != enumver) { 00472 /* Ooh, a reload... */ 00473 s = toplevs; 00474 version = enumver; 00475 } else { 00476 s = s->next; 00477 } 00478 ast_mutex_unlock(&enumlock); 00479 00480 if (!s) 00481 break; 00482 00483 ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos); 00484 ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback); 00485 ast_debug(1, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret); 00486 if (ret > 0) 00487 break; 00488 } 00489 } 00490 00491 if (ret < 0) { 00492 ast_debug(1, "No such number found: %s (%s)\n", tmp, strerror(errno)); 00493 strcpy(dst, "0"); 00494 ret = 0; 00495 } 00496 00497 if (context->naptr_rrs_count >= context->position && ! (context->options & ENUMLOOKUP_OPTIONS_COUNT)) { 00498 /* sort array by NAPTR order/preference */ 00499 for (k = 0; k < context->naptr_rrs_count; k++) { 00500 for (i = 0; i < context->naptr_rrs_count; i++) { 00501 /* use order first and then preference to compare */ 00502 if ((ntohs(context->naptr_rrs[k].naptr.order) < ntohs(context->naptr_rrs[i].naptr.order) 00503 && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos) 00504 || (ntohs(context->naptr_rrs[k].naptr.order) > ntohs(context->naptr_rrs[i].naptr.order) 00505 && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)){ 00506 z = context->naptr_rrs[k].sort_pos; 00507 context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos; 00508 context->naptr_rrs[i].sort_pos = z; 00509 continue; 00510 } 00511 if (ntohs(context->naptr_rrs[k].naptr.order) == ntohs(context->naptr_rrs[i].naptr.order)) { 00512 if ((ntohs(context->naptr_rrs[k].naptr.pref) < ntohs(context->naptr_rrs[i].naptr.pref) 00513 && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos) 00514 || (ntohs(context->naptr_rrs[k].naptr.pref) > ntohs(context->naptr_rrs[i].naptr.pref) 00515 && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)){ 00516 z = context->naptr_rrs[k].sort_pos; 00517 context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos; 00518 context->naptr_rrs[i].sort_pos = z; 00519 } 00520 } 00521 } 00522 } 00523 for (k = 0; k < context->naptr_rrs_count; k++) { 00524 if (context->naptr_rrs[k].sort_pos == context->position - 1) { 00525 ast_copy_string(context->dst, context->naptr_rrs[k].result, dstlen); 00526 ast_copy_string(context->tech, context->naptr_rrs[k].tech, techlen); 00527 break; 00528 } 00529 } 00530 } else if (!(context->options & ENUMLOOKUP_OPTIONS_COUNT)) { 00531 context->dst[0] = 0; 00532 } 00533 if (chan) 00534 ret |= ast_autoservice_stop(chan); 00535 00536 if (!argcontext) { 00537 for (k = 0; k < context->naptr_rrs_count; k++) { 00538 ast_free(context->naptr_rrs[k].result); 00539 ast_free(context->naptr_rrs[k].tech); 00540 } 00541 ast_free(context->naptr_rrs); 00542 ast_free(context); 00543 } else 00544 *argcontext = context; 00545 00546 return ret; 00547 }
int ast_get_txt | ( | struct ast_channel * | chan, | |
const char * | number, | |||
char * | location, | |||
int | maxloc, | |||
char * | technology, | |||
int | maxtech, | |||
char * | txt, | |||
int | maxtxt | |||
) |
Lookup DNS TXT record (used by app TXTCIDnum.
chan | Channel | |
number | E164 number with or without the leading + | |
location | Number returned (or SIP uri) | |
maxloc | Max length of number | |
technology | Technology (not used in TXT records) | |
maxtech | Max length | |
txt | Text string (return value) | |
maxtxt | Max length of "txt" |
Definition at line 550 of file enum.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), chan, context, enumlock, enumver, errno, enum_context::naptrinput, s, toplevs, txt_callback(), and version.
Referenced by function_txtcidname().
00551 { 00552 struct enum_context context; 00553 char tmp[259 + 512]; 00554 char naptrinput[512] = "+"; 00555 int pos = strlen(number) - 1; 00556 int newpos = 0; 00557 int ret = -1; 00558 struct enum_search *s = NULL; 00559 int version = -1; 00560 00561 strncat(naptrinput, number, sizeof(naptrinput) - 2); 00562 00563 context.naptrinput = naptrinput; 00564 context.dst = dst; 00565 context.dstlen = dstlen; 00566 context.tech = tech; 00567 context.techlen = techlen; 00568 context.txt = txt; 00569 context.txtlen = txtlen; 00570 00571 if (pos > 128) 00572 pos = 128; 00573 while (pos >= 0) { 00574 tmp[newpos++] = number[pos--]; 00575 tmp[newpos++] = '.'; 00576 } 00577 00578 if (chan && ast_autoservice_start(chan) < 0) 00579 return -1; 00580 00581 for (;;) { 00582 ast_mutex_lock(&enumlock); 00583 if (version != enumver) { 00584 /* Ooh, a reload... */ 00585 s = toplevs; 00586 version = enumver; 00587 } else { 00588 s = s->next; 00589 } 00590 if (s) { 00591 ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos); 00592 } 00593 ast_mutex_unlock(&enumlock); 00594 if (!s) 00595 break; 00596 00597 ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback); 00598 if (ret > 0) 00599 break; 00600 } 00601 if (ret < 0) { 00602 ast_debug(2, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno)); 00603 ret = 0; 00604 } 00605 if (chan) 00606 ret |= ast_autoservice_stop(chan); 00607 return ret; 00608 }
static int enum_callback | ( | void * | context, | |
unsigned char * | answer, | |||
int | len, | |||
unsigned char * | fullanswer | |||
) | [static] |
Callback from ENUM lookup function.
Definition at line 343 of file enum.c.
References ast_log(), ast_realloc, ast_strdup, ast_strlen_zero(), enum_context::dst, enum_context::dstlen, ENUMLOOKUP_OPTIONS_COUNT, LOG_WARNING, enum_naptr_rr::naptr, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_context::options, parse_naptr(), enum_context::position, enum_naptr_rr::result, enum_naptr_rr::sort_pos, enum_naptr_rr::tech, enum_context::tech, and enum_context::techlen.
Referenced by ast_get_enum().
00344 { 00345 struct enum_context *c = context; 00346 void *p = NULL; 00347 int res; 00348 00349 res = parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput); 00350 00351 if (res < 0) { 00352 ast_log(LOG_WARNING, "Failed to parse naptr :(\n"); 00353 return -1; 00354 } else if (res > 0 && !ast_strlen_zero(c->dst)){ /* ok, we got needed NAPTR */ 00355 if (c->options & ENUMLOOKUP_OPTIONS_COUNT){ /* counting RRs */ 00356 c->position++; 00357 snprintf(c->dst, c->dstlen, "%d", c->position); 00358 } else { 00359 if ((p = ast_realloc(c->naptr_rrs, sizeof(*c->naptr_rrs) * (c->naptr_rrs_count + 1)))) { 00360 c->naptr_rrs = p; 00361 memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(c->naptr_rrs->naptr)); 00362 c->naptr_rrs[c->naptr_rrs_count].result = ast_strdup(c->dst); 00363 c->naptr_rrs[c->naptr_rrs_count].tech = ast_strdup(c->tech); 00364 c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count; 00365 c->naptr_rrs_count++; 00366 } 00367 c->dst[0] = 0; 00368 } 00369 return 0; 00370 } 00371 00372 if (c->options & ENUMLOOKUP_OPTIONS_COUNT) { /* counting RRs */ 00373 snprintf(c->dst, c->dstlen, "%d", c->position); 00374 } 00375 00376 return 0; 00377 }
static struct enum_search* enum_newtoplev | ( | const char * | s | ) | [static] |
Add enum tree to linked list.
Definition at line 611 of file enum.c.
References ast_calloc, and ast_copy_string().
Referenced by private_enum_init().
00612 { 00613 struct enum_search *tmp; 00614 00615 if ((tmp = ast_calloc(1, sizeof(*tmp)))) { 00616 ast_copy_string(tmp->toplev, s, sizeof(tmp->toplev)); 00617 } 00618 return tmp; 00619 }
static unsigned int parse_ie | ( | char * | data, | |
unsigned int | maxdatalen, | |||
unsigned char * | src, | |||
unsigned int | srclen | |||
) | [static] |
Parse NAPTR record information elements.
Definition at line 89 of file enum.c.
References ast_log(), len(), and LOG_WARNING.
Referenced by parse_naptr().
00090 { 00091 unsigned int len, olen; 00092 00093 len = olen = (unsigned int) src[0]; 00094 src++; 00095 srclen--; 00096 00097 if (len > srclen) { 00098 ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %d characters, got %d\n", len, srclen); 00099 return -1; 00100 } 00101 00102 if (len > maxdatalen) 00103 len = maxdatalen; 00104 memcpy(data, src, len); 00105 00106 return olen + 1; 00107 }
static int parse_naptr | ( | char * | dst, | |
int | dstsize, | |||
char * | tech, | |||
int | techsize, | |||
unsigned char * | answer, | |||
int | len, | |||
char * | naptrinput | |||
) | [static] |
Parse DNS NAPTR record used in ENUM ---.
Definition at line 110 of file enum.c.
References ARRAY_LEN, ast_copy_string(), ast_debug, ast_log(), LOG_WARNING, and parse_ie().
Referenced by enum_callback().
00111 { 00112 char tech_return[80]; 00113 unsigned char *oanswer = answer; 00114 char flags[512] = ""; 00115 char services[512] = ""; 00116 char *p; 00117 char regexp[512] = ""; 00118 char repl[512] = ""; 00119 char tempdst[512] = ""; 00120 char errbuff[512] = ""; 00121 char delim; 00122 char *delim2; 00123 char *pattern, *subst, *d; 00124 int res; 00125 int regexp_len, rc; 00126 int size, matchindex; /* size is the size of the backreference sub. */ 00127 int d_len = sizeof(tempdst) - 1; 00128 static const int max_bt = 10; /* max num of regexp backreference allowed, must remain 10 to guarantee a valid backreference index */ 00129 regex_t preg; 00130 regmatch_t pmatch[max_bt]; 00131 00132 tech_return[0] = '\0'; 00133 00134 dst[0] = '\0'; 00135 00136 if (len < sizeof(struct naptr)) { 00137 ast_log(LOG_WARNING, "NAPTR record length too short\n"); 00138 return -1; 00139 } 00140 answer += sizeof(struct naptr); 00141 len -= sizeof(struct naptr); 00142 if ((res = parse_ie(flags, sizeof(flags) - 1, answer, len)) < 0) { 00143 ast_log(LOG_WARNING, "Failed to get flags from NAPTR record\n"); 00144 return -1; 00145 } else { 00146 answer += res; 00147 len -= res; 00148 } 00149 if ((res = parse_ie(services, sizeof(services) - 1, answer, len)) < 0) { 00150 ast_log(LOG_WARNING, "Failed to get services from NAPTR record\n"); 00151 return -1; 00152 } else { 00153 answer += res; 00154 len -= res; 00155 } 00156 if ((res = parse_ie(regexp, sizeof(regexp) - 1, answer, len)) < 0) { 00157 ast_log(LOG_WARNING, "Failed to get regexp from NAPTR record\n"); 00158 return -1; 00159 } else { 00160 answer += res; 00161 len -= res; 00162 } 00163 00164 if ((res = dn_expand(oanswer, answer + len, answer, repl, sizeof(repl) - 1)) < 0) { 00165 ast_log(LOG_WARNING, "Failed to expand hostname\n"); 00166 return -1; 00167 } 00168 00169 ast_debug(3, "NAPTR input='%s', flags='%s', services='%s', regexp='%s', repl='%s'\n", 00170 naptrinput, flags, services, regexp, repl); 00171 00172 if (tolower(flags[0]) != 'u') { 00173 ast_log(LOG_WARNING, "NAPTR Flag must be 'U' or 'u'.\n"); 00174 return -1; 00175 } 00176 00177 p = strstr(services, "e2u+"); 00178 if (p == NULL) 00179 p = strstr(services, "E2U+"); 00180 if (p){ 00181 p = p + 4; 00182 if (strchr(p, ':')){ 00183 p = strchr(p, ':') + 1; 00184 } 00185 ast_copy_string(tech_return, p, sizeof(tech_return)); 00186 } else { 00187 00188 p = strstr(services, "+e2u"); 00189 if (p == NULL) 00190 p = strstr(services, "+E2U"); 00191 if (p) { 00192 *p = 0; 00193 p = strchr(services, ':'); 00194 if (p) 00195 *p = 0; 00196 ast_copy_string(tech_return, services, sizeof(tech_return)); 00197 } 00198 } 00199 00200 regexp_len = strlen(regexp); 00201 if (regexp_len < 7) { 00202 ast_log(LOG_WARNING, "Regex too short to be meaningful.\n"); 00203 return -1; 00204 } 00205 00206 /* this takes the first character of the regexp (which is a delimiter) 00207 * and uses that character to find the index of the second delimiter */ 00208 delim = regexp[0]; 00209 delim2 = strchr(regexp + 1, delim); 00210 if ((delim2 == NULL) || (regexp[regexp_len - 1] != delim)) { /* is the second delimiter found, and is the end of the regexp a delimiter */ 00211 ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp); 00212 return -1; 00213 } else if (strchr((delim2 + 1), delim) == NULL) { /* if the second delimiter is found, make sure there is a third instance. this could be the end one instead of the middle */ 00214 ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp); 00215 return -1; 00216 } 00217 pattern = regexp + 1; /* pattern is the regex without the begining and ending delimiter */ 00218 *delim2 = 0; /* zero out the middle delimiter */ 00219 subst = delim2 + 1; /* dst substring is everything after the second delimiter. */ 00220 regexp[regexp_len - 1] = 0; /* zero out the last delimiter */ 00221 00222 /* 00223 * now do the regex wizardry. 00224 */ 00225 00226 if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) { 00227 ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n", regexp); 00228 return -1; 00229 } 00230 00231 if (preg.re_nsub > ARRAY_LEN(pmatch)) { 00232 ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n"); 00233 regfree(&preg); 00234 return -1; 00235 } 00236 /* pmatch is an array containing the substring indexes for the regex backreference sub. 00237 * max_bt is the maximum number of backreferences allowed to be stored in pmatch */ 00238 if ((rc = regexec(&preg, (char *) naptrinput, max_bt, pmatch, 0))) { 00239 regerror(rc, &preg, errbuff, sizeof(errbuff)); 00240 ast_log(LOG_WARNING, "NAPTR Regex match failed. Reason: %s\n", errbuff); 00241 regfree(&preg); 00242 return -1; 00243 } 00244 regfree(&preg); 00245 00246 d = tempdst; 00247 d_len--; 00248 00249 /* perform the backreference sub. Search the subst for backreferences, 00250 * when a backreference is found, retrieve the backreferences number. 00251 * use the backreference number as an index for pmatch to retrieve the 00252 * beginning and ending indexes of the substring to insert as the backreference. 00253 * if no backreference is found, continue copying the subst into tempdst */ 00254 while (*subst && (d_len > 0)) { 00255 if ((subst[0] == '\\') && isdigit(subst[1])) { /* is this character the beginning of a backreference */ 00256 matchindex = (int) (subst[1] - '0'); 00257 if (matchindex >= ARRAY_LEN(pmatch)) { 00258 ast_log(LOG_WARNING, "Error during regex substitution. Invalid pmatch index.\n"); 00259 return -1; 00260 } 00261 /* pmatch len is 10. we are garanteed a single char 0-9 is a valid index */ 00262 size = pmatch[matchindex].rm_eo - pmatch[matchindex].rm_so; 00263 if (size > d_len) { 00264 ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n"); 00265 return -1; 00266 } 00267 /* are the pmatch indexes valid for the input length */ 00268 if ((strlen((char *) naptrinput) >= pmatch[matchindex].rm_eo) && (pmatch[matchindex].rm_so <= pmatch[matchindex].rm_eo)) { 00269 memcpy(d, (naptrinput + (int) pmatch[matchindex].rm_so), size); /* copy input substring into backreference marker */ 00270 d_len -= size; 00271 subst += 2; /* skip over backreference characters to next valid character */ 00272 d += size; 00273 } else { 00274 ast_log(LOG_WARNING, "Error during regex substitution. Invalid backreference index.\n"); 00275 return -1; 00276 } 00277 } else if (isprint(*subst)) { 00278 *d++ = *subst++; 00279 d_len--; 00280 } else { 00281 ast_log(LOG_WARNING, "Error during regex substitution.\n"); 00282 return -1; 00283 } 00284 } 00285 *d = 0; 00286 ast_copy_string((char *) dst, tempdst, dstsize); 00287 dst[dstsize - 1] = '\0'; 00288 00289 if (*tech != '\0'){ /* check if it is requested NAPTR */ 00290 if (!strncasecmp(tech, "ALL", techsize)){ 00291 return 1; /* return or count any RR */ 00292 } 00293 if (!strncasecmp(tech_return, tech, sizeof(tech_return)<techsize?sizeof(tech_return):techsize)){ 00294 ast_copy_string(tech, tech_return, techsize); 00295 return 1; /* we got out RR */ 00296 } else { /* go to the next RR in the DNS answer */ 00297 return 0; 00298 } 00299 } 00300 00301 /* tech was not specified, return first parsed RR */ 00302 ast_copy_string(tech, tech_return, techsize); 00303 return 1; 00304 }
static int private_enum_init | ( | int | reload | ) | [static] |
Initialize the ENUM support subsystem.
Definition at line 622 of file enum.c.
References ast_config_destroy(), ast_config_load, ast_free, ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, enum_newtoplev(), enumlock, enumver, EVENT_FLAG_SYSTEM, manager_event, ast_variable::name, ast_variable::next, s, TOPLEV, toplevs, and ast_variable::value.
Referenced by ast_enum_init(), and ast_enum_reload().
00623 { 00624 struct ast_config *cfg; 00625 struct enum_search *s, *sl; 00626 struct ast_variable *v; 00627 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 00628 00629 if ((cfg = ast_config_load("enum.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) 00630 return 0; 00631 00632 /* Destroy existing list */ 00633 ast_mutex_lock(&enumlock); 00634 s = toplevs; 00635 while (s) { 00636 sl = s; 00637 s = s->next; 00638 ast_free(sl); 00639 } 00640 toplevs = NULL; 00641 if (cfg) { 00642 sl = NULL; 00643 v = ast_variable_browse(cfg, "general"); 00644 while (v) { 00645 if (!strcasecmp(v->name, "search")) { 00646 s = enum_newtoplev(v->value); 00647 if (s) { 00648 if (sl) 00649 sl->next = s; 00650 else 00651 toplevs = s; 00652 sl = s; 00653 } 00654 } 00655 v = v->next; 00656 } 00657 ast_config_destroy(cfg); 00658 } else { 00659 toplevs = enum_newtoplev(TOPLEV); 00660 } 00661 enumver++; 00662 ast_mutex_unlock(&enumlock); 00663 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: Enum\r\nStatus: Enabled\r\nMessage: ENUM reload Requested\r\n"); 00664 return 0; 00665 }
static int txt_callback | ( | void * | context, | |
unsigned char * | answer, | |||
int | len, | |||
unsigned char * | fullanswer | |||
) | [static] |
Callback for TXT record lookup.
Definition at line 311 of file enum.c.
References ast_copy_string(), enum_context::txt, and enum_context::txtlen.
Referenced by ast_get_txt().
00312 { 00313 struct enum_context *c = (struct enum_context *)context; 00314 00315 if (answer == NULL) { 00316 c->txt = NULL; 00317 c->txtlen = 0; 00318 return 0; 00319 } 00320 00321 /* skip over first byte, as for some reason it's a vertical tab character */ 00322 answer += 1; 00323 len -= 1; 00324 00325 /* answer is not null-terminated, but should be */ 00326 /* this is safe to do, as answer has extra bytes on the end we can 00327 * safely overwrite with a null */ 00328 answer[len] = '\0'; 00329 /* now increment len so that len includes the null, so that we can 00330 * compare apples to apples */ 00331 len +=1; 00332 00333 /* finally, copy the answer into c->txt */ 00334 ast_copy_string(c->txt, (const char *) answer, len < c->txtlen ? len : (c->txtlen)); 00335 00336 /* just to be safe, let's make sure c->txt is null terminated */ 00337 c->txt[(c->txtlen) - 1] = '\0'; 00338 00339 return 1; 00340 }
ast_mutex_t enumlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 86 of file enum.c.
Referenced by ast_get_enum(), ast_get_txt(), and private_enum_init().
int enumver [static] |
struct enum_search * toplevs [static] |
Referenced by ast_get_enum(), ast_get_txt(), and private_enum_init().