#include "asterisk/channel.h"
Go to the source code of this file.
Functions | |
int | ast_enum_init (void) |
Initialize the ENUM support subsystem. | |
int | ast_enum_reload (void) |
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) |
Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup. | |
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. |
Definition in file enum.h.
int ast_enum_init | ( | void | ) |
Initialize the ENUM support subsystem.
Definition at line 646 of file enum.c.
References ast_config_destroy(), ast_config_load(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), enum_newtoplev(), enumlock, free, ast_variable::name, ast_variable::next, s, TOPLEV, toplevs, and ast_variable::value.
Referenced by ast_enum_reload(), and main().
00647 { 00648 struct ast_config *cfg; 00649 struct enum_search *s, *sl; 00650 struct ast_variable *v; 00651 00652 /* Destroy existing list */ 00653 ast_mutex_lock(&enumlock); 00654 s = toplevs; 00655 while(s) { 00656 sl = s; 00657 s = s->next; 00658 free(sl); 00659 } 00660 toplevs = NULL; 00661 cfg = ast_config_load("enum.conf"); 00662 if (cfg) { 00663 sl = NULL; 00664 v = ast_variable_browse(cfg, "general"); 00665 while(v) { 00666 if (!strcasecmp(v->name, "search")) { 00667 s = enum_newtoplev(v->value); 00668 if (s) { 00669 if (sl) 00670 sl->next = s; 00671 else 00672 toplevs = s; 00673 sl = s; 00674 } 00675 } 00676 v = v->next; 00677 } 00678 ast_config_destroy(cfg); 00679 } else { 00680 toplevs = enum_newtoplev(TOPLEV); 00681 } 00682 enumver++; 00683 ast_mutex_unlock(&enumlock); 00684 return 0; 00685 }
int ast_enum_reload | ( | void | ) |
Definition at line 687 of file enum.c.
References ast_enum_init().
00688 { 00689 return ast_enum_init(); 00690 }
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 | |||
) |
Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup.
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 |
Definition at line 409 of file enum.c.
References ast_autoservice_start(), ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enum_callback(), enumlock, ENUMLOOKUP_OPTIONS_COUNT, errno, LOG_DEBUG, enum_context::naptrinput, s, and toplevs.
Referenced by function_enum().
00410 { 00411 struct enum_context context; 00412 char tmp[259 + 512]; 00413 char naptrinput[512]; 00414 int pos = strlen(number) - 1; 00415 int newpos = 0; 00416 int ret = -1; 00417 struct enum_search *s = NULL; 00418 int version = -1; 00419 /* for ISN rewrite */ 00420 char *p1 = NULL; 00421 char *p2 = NULL; 00422 int k = 0; 00423 int i = 0; 00424 int z = 0; 00425 00426 ast_copy_string(naptrinput, number[0] == 'n' ? number+1 : number, sizeof(naptrinput)); 00427 00428 context.naptrinput = naptrinput; /* The number */ 00429 context.dst = dst; /* Return string */ 00430 context.dstlen = dstlen; 00431 context.tech = tech; 00432 context.techlen = techlen; 00433 context.options = 0; 00434 context.position = record > 0 ? record : 1; 00435 context.naptr_rrs = NULL; 00436 context.naptr_rrs_count = 0; 00437 00438 if (options != NULL) { 00439 if (*options == 'c') { 00440 context.options = ENUMLOOKUP_OPTIONS_COUNT; 00441 context.position = 0; 00442 } 00443 } 00444 00445 ast_log(LOG_DEBUG, "ast_get_enum(): n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n", 00446 number, tech, suffix, context.options, context.position); 00447 00448 if (pos > 128) 00449 pos = 128; 00450 00451 /* ISN rewrite */ 00452 p1 = strchr(number, '*'); 00453 00454 if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */ 00455 p1 = NULL; 00456 k = 1; /* strip 'n' from number */ 00457 } 00458 00459 if (p1 != NULL) { 00460 p2 = p1+1; 00461 while (p1 > number){ 00462 p1--; 00463 tmp[newpos++] = *p1; 00464 tmp[newpos++] = '.'; 00465 } 00466 if (*p2) { 00467 while(*p2 && newpos < 128){ 00468 tmp[newpos++] = *p2; 00469 p2++; 00470 } 00471 tmp[newpos++] = '.'; 00472 } 00473 00474 } else { 00475 while (pos >= k) { 00476 if (isdigit(number[pos])) { 00477 tmp[newpos++] = number[pos]; 00478 tmp[newpos++] = '.'; 00479 } 00480 pos--; 00481 } 00482 } 00483 00484 if (chan && ast_autoservice_start(chan) < 0) 00485 return -1; 00486 00487 if(suffix) { 00488 ast_copy_string(tmp + newpos, suffix, sizeof(tmp) - newpos); 00489 ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback); 00490 ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret); 00491 } else { 00492 ret = -1; /* this is actually dead code since the demise of app_enum.c */ 00493 for (;;) { 00494 ast_mutex_lock(&enumlock); 00495 if (version != enumver) { 00496 /* Ooh, a reload... */ 00497 s = toplevs; 00498 version = enumver; 00499 } else { 00500 s = s->next; 00501 } 00502 ast_mutex_unlock(&enumlock); 00503 00504 if (!s) 00505 break; 00506 00507 ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos); 00508 ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback); 00509 ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret); 00510 if (ret > 0) 00511 break; 00512 } 00513 } 00514 00515 if (ret < 0) { 00516 ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno)); 00517 strcpy(dst, "0"); 00518 ret = 0; 00519 } 00520 00521 if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) { 00522 /* sort array by NAPTR order/preference */ 00523 for (k = 0; k < context.naptr_rrs_count; k++) { 00524 for (i = 0; i < context.naptr_rrs_count; i++) { 00525 /* use order first and then preference to compare */ 00526 if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order) 00527 && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos) 00528 || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order) 00529 && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){ 00530 z = context.naptr_rrs[k].sort_pos; 00531 context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos; 00532 context.naptr_rrs[i].sort_pos = z; 00533 continue; 00534 } 00535 if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) { 00536 if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref) 00537 && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos) 00538 || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref) 00539 && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){ 00540 z = context.naptr_rrs[k].sort_pos; 00541 context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos; 00542 context.naptr_rrs[i].sort_pos = z; 00543 } 00544 } 00545 } 00546 } 00547 for (k = 0; k < context.naptr_rrs_count; k++) { 00548 if (context.naptr_rrs[k].sort_pos == context.position-1) { 00549 ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen); 00550 ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen); 00551 break; 00552 } 00553 } 00554 } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) { 00555 context.dst[0] = 0; 00556 } 00557 if (chan) 00558 ret |= ast_autoservice_stop(chan); 00559 00560 for (k = 0; k < context.naptr_rrs_count; k++) { 00561 free(context.naptr_rrs[k].result); 00562 free(context.naptr_rrs[k].tech); 00563 } 00564 00565 free(context.naptr_rrs); 00566 00567 return ret; 00568 }
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 573 of file enum.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enumlock, errno, LOG_DEBUG, enum_context::naptrinput, option_debug, s, toplevs, and txt_callback().
Referenced by function_txtcidname().
00574 { 00575 struct enum_context context; 00576 char tmp[259 + 512]; 00577 char naptrinput[512] = "+"; 00578 int pos = strlen(number) - 1; 00579 int newpos = 0; 00580 int ret = -1; 00581 struct enum_search *s = NULL; 00582 int version = -1; 00583 00584 strncat(naptrinput, number, sizeof(naptrinput) - 2); 00585 00586 context.naptrinput = naptrinput; 00587 context.dst = dst; 00588 context.dstlen = dstlen; 00589 context.tech = tech; 00590 context.techlen = techlen; 00591 context.txt = txt; 00592 context.txtlen = txtlen; 00593 00594 if (pos > 128) 00595 pos = 128; 00596 while (pos >= 0) { 00597 tmp[newpos++] = number[pos--]; 00598 tmp[newpos++] = '.'; 00599 } 00600 00601 if (chan && ast_autoservice_start(chan) < 0) 00602 return -1; 00603 00604 for (;;) { 00605 ast_mutex_lock(&enumlock); 00606 if (version != enumver) { 00607 /* Ooh, a reload... */ 00608 s = toplevs; 00609 version = enumver; 00610 } else { 00611 s = s->next; 00612 } 00613 if (s) { 00614 ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos); 00615 } 00616 ast_mutex_unlock(&enumlock); 00617 if (!s) 00618 break; 00619 00620 ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback); 00621 if (ret > 0) 00622 break; 00623 } 00624 if (ret < 0) { 00625 if (option_debug > 1) 00626 ast_log(LOG_DEBUG, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno)); 00627 ret = 0; 00628 } 00629 if (chan) 00630 ret |= ast_autoservice_stop(chan); 00631 return ret; 00632 }