Sun Aug 6 15:10:41 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

enum.h File Reference

DNS and ENUM functions. More...

#include "asterisk/channel.h"

Include dependency graph for enum.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int ast_enum_init (void)
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)
 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.


Detailed Description

DNS and ENUM functions.

Definition in file enum.h.


Function Documentation

int ast_enum_init void   ) 
 

Definition at line 614 of file enum.c.

References ast_config_destroy(), ast_config_load(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), cfg, enum_newtoplev(), enumver, free, ast_variable::name, ast_variable::next, enum_search::next, s, TOPLEV, toplevs, and ast_variable::value.

Referenced by ast_enum_reload(), and main().

00615 {
00616    struct ast_config *cfg;
00617    struct enum_search *s, *sl;
00618    struct ast_variable *v;
00619 
00620    /* Destroy existing list */
00621    ast_mutex_lock(&enumlock);
00622    s = toplevs;
00623    while(s) {
00624       sl = s;
00625       s = s->next;
00626       free(sl);
00627    }
00628    toplevs = NULL;
00629    cfg = ast_config_load("enum.conf");
00630    if (cfg) {
00631       sl = NULL;
00632       v = ast_variable_browse(cfg, "general");
00633       while(v) {
00634          if (!strcasecmp(v->name, "search")) {
00635             s = enum_newtoplev(v->value);
00636             if (s) {
00637                if (sl)
00638                   sl->next = s;
00639                else
00640                   toplevs = s;
00641                sl = s;
00642             }
00643          }
00644          v = v->next;
00645       }
00646       ast_config_destroy(cfg);
00647    } else {
00648       toplevs = enum_newtoplev(TOPLEV);
00649    }
00650    enumver++;
00651    ast_mutex_unlock(&enumlock);
00652    return 0;
00653 }

int ast_enum_reload void   ) 
 

Definition at line 655 of file enum.c.

References ast_enum_init().

Referenced by ast_module_reload(), and main().

00656 {
00657    return ast_enum_init();
00658 }

int ast_get_enum struct ast_channel chan,
const char *  number,
char *  location,
int  maxloc,
char *  technology,
int  maxtech,
char *  suffix,
char *  options
 

Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup.

Parameters:
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, or number - the position of required RR in the answer list

Definition at line 376 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), enum_context::dst, enum_context::dstlen, enum_callback(), ENUMLOOKUP_OPTIONS_COUNT, enumver, free, LOG_DEBUG, enum_naptr_rr::naptr, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_search::next, enum_context::options, naptr::order, enum_context::position, naptr::pref, enum_naptr_rr::result, s, enum_naptr_rr::sort_pos, enum_naptr_rr::tech, enum_context::tech, enum_context::techlen, enum_search::toplev, and toplevs.

Referenced by enumlookup_exec(), and function_enum().

00377 {
00378    struct enum_context context;
00379    char tmp[259 + 512];
00380    char naptrinput[512];
00381    int pos = strlen(number) - 1;
00382    int newpos = 0;
00383    int ret = -1;
00384    struct enum_search *s = NULL;
00385    int version = -1;
00386    /* for ISN rewrite */
00387    char *p1 = NULL;
00388    char *p2 = NULL;
00389    int k = 0;
00390    int i = 0;
00391    int z = 0;
00392 
00393    if (number[0] == 'n') {
00394       strncpy(naptrinput, number+1, sizeof(naptrinput));
00395    } else {
00396       strncpy(naptrinput, number, sizeof(naptrinput));
00397    }
00398 
00399    context.naptrinput = naptrinput; /* The number */
00400    context.dst = dst;         /* Return string */
00401    context.dstlen = dstlen;
00402    context.tech = tech;
00403    context.techlen = techlen;
00404    context.options = 0;
00405    context.position = 1;
00406    context.naptr_rrs = NULL;
00407    context.naptr_rrs_count = 0;
00408 
00409    if (options != NULL){
00410       if (*options == 'c'){
00411          context.options = ENUMLOOKUP_OPTIONS_COUNT;
00412          context.position = 0;
00413       } else {
00414          context.position = atoi(options);
00415          if (context.position < 1)
00416             context.position = 1;
00417       }
00418    }
00419 
00420    if (pos > 128)
00421       pos = 128;
00422 
00423    /* ISN rewrite */
00424    p1 = strchr(number, '*');
00425 
00426    if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */
00427       p1 = NULL;
00428       k = 1; /* strip 'n' from number */
00429    }
00430 
00431    if (p1 != NULL) {
00432       p2 = p1+1;
00433       while (p1 > number){
00434          p1--;
00435          tmp[newpos++] = *p1;
00436          tmp[newpos++] = '.';
00437       }
00438       if (*p2) {
00439          while(*p2 && newpos < 128){
00440             tmp[newpos++] = *p2;
00441             p2++;
00442          }
00443          tmp[newpos++] = '.';
00444       }
00445 
00446    } else {
00447       while (pos >= k) {
00448          if (isdigit(number[pos])) {
00449             tmp[newpos++] = number[pos];
00450             tmp[newpos++] = '.';
00451          }
00452          pos--;
00453       }
00454    }
00455 
00456    if (chan && ast_autoservice_start(chan) < 0)
00457       return -1;
00458 
00459    for (;;) {
00460       ast_mutex_lock(&enumlock);
00461       if (version != enumver) {
00462          /* Ooh, a reload... */
00463          s = toplevs;
00464          version = enumver;
00465       } else {
00466          s = s->next;
00467       }
00468       if (suffix != NULL) {
00469          strncpy(tmp + newpos, suffix, sizeof(tmp) - newpos - 1);
00470       } else if (s) {
00471          strncpy(tmp + newpos, s->toplev, sizeof(tmp) - newpos - 1);
00472       }
00473       ast_mutex_unlock(&enumlock);
00474       if (!s)
00475          break;
00476       ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
00477       if (ret > 0)
00478          break;
00479       if (suffix != NULL)
00480                        break;
00481    }
00482    if (ret < 0) {
00483       ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
00484       ret = 0;
00485    }
00486 
00487        if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00488                /* sort array by NAPTR order/preference */
00489                for (k=0; k<context.naptr_rrs_count; k++) {
00490                        for (i=0; i<context.naptr_rrs_count; i++) {
00491                                /* use order first and then preference to compare */
00492                                if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
00493                                                && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00494                                        || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
00495                                                && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00496                                        z = context.naptr_rrs[k].sort_pos;
00497                                        context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00498                                        context.naptr_rrs[i].sort_pos = z;
00499                                        continue;
00500                                }
00501                                if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
00502                                        if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
00503                                                        && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00504                                                || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
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                                        }
00510                                }
00511                        }
00512                }
00513                for (k=0; k<context.naptr_rrs_count; k++) {
00514                        if (context.naptr_rrs[k].sort_pos == context.position-1) {
00515                                ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
00516                                ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
00517                                break;
00518                        }
00519                }
00520        } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00521                context.dst[0] = 0;
00522        }
00523 
00524    if (chan)
00525       ret |= ast_autoservice_stop(chan);
00526 
00527    for (k=0; k<context.naptr_rrs_count; k++) {
00528       free(context.naptr_rrs[k].result);
00529       free(context.naptr_rrs[k].tech);
00530    }
00531 
00532    free(context.naptr_rrs);
00533 
00534    return ret;
00535 }

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.

Parameters:
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 540 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), enum_context::dst, enum_context::dstlen, enumver, LOG_DEBUG, enum_context::naptrinput, enum_search::next, s, enum_context::tech, enum_context::techlen, toplevs, enum_context::txt, txt_callback(), and enum_context::txtlen.

Referenced by function_txtcidname(), and txtcidname_exec().

00541 {
00542    struct enum_context context;
00543    char tmp[259 + 512];
00544    char naptrinput[512] = "+";
00545    int pos = strlen(number) - 1;
00546    int newpos = 0;
00547    int ret = -1;
00548    struct enum_search *s = NULL;
00549    int version = -1;
00550 
00551    strncat(naptrinput, number, sizeof(naptrinput) - 2);
00552 
00553    context.naptrinput = naptrinput;
00554    context.dst = dst;
00555    context.dstlen = dstlen;
00556    context.tech = tech;
00557    context.techlen = techlen;
00558    context.txt = txt;
00559    context.txtlen = txtlen;
00560 
00561    if (pos > 128)
00562       pos = 128;
00563    while (pos >= 0) {
00564       tmp[newpos++] = number[pos--];
00565       tmp[newpos++] = '.';
00566    }
00567 
00568    if (chan && ast_autoservice_start(chan) < 0)
00569       return -1;
00570 
00571    for (;;) {
00572       ast_mutex_lock(&enumlock);
00573       if (version != enumver) {
00574          /* Ooh, a reload... */
00575          s = toplevs;
00576          version = enumver;
00577       } else {
00578          s = s->next;
00579       }
00580       if (s) {
00581          strncpy(tmp + newpos, s->toplev, sizeof(tmp) - newpos - 1);
00582       }
00583       ast_mutex_unlock(&enumlock);
00584       if (!s)
00585          break;
00586 
00587       ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback);
00588       if (ret > 0)
00589          break;
00590    }
00591    if (ret < 0) {
00592       ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
00593       ret = 0;
00594    }
00595    if (chan)
00596       ret |= ast_autoservice_stop(chan);
00597    return ret;
00598 }


Generated on Sun Aug 6 15:10:42 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2