Wed Aug 15 01:25:07 2007

Asterisk developer's documentation


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)
 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.


Detailed Description

DNS and ENUM functions.

Definition in file enum.h.


Function Documentation

int ast_enum_init ( void   ) 

Initialize the ENUM support subsystem.

Definition at line 627 of file enum.c.

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

00628 {
00629    struct ast_config *cfg;
00630    struct enum_search *s, *sl;
00631    struct ast_variable *v;
00632 
00633    /* Destroy existing list */
00634    ast_mutex_lock(&enumlock);
00635    s = toplevs;
00636    while(s) {
00637       sl = s;
00638       s = s->next;
00639       free(sl);
00640    }
00641    toplevs = NULL;
00642    cfg = ast_config_load("enum.conf");
00643    if (cfg) {
00644       sl = NULL;
00645       v = ast_variable_browse(cfg, "general");
00646       while(v) {
00647          if (!strcasecmp(v->name, "search")) {
00648             s = enum_newtoplev(v->value);
00649             if (s) {
00650                if (sl)
00651                   sl->next = s;
00652                else
00653                   toplevs = s;
00654                sl = s;
00655             }
00656          }
00657          v = v->next;
00658       }
00659       ast_config_destroy(cfg);
00660    } else {
00661       toplevs = enum_newtoplev(TOPLEV);
00662    }
00663    enumver++;
00664    ast_mutex_unlock(&enumlock);
00665    return 0;
00666 }

int ast_enum_reload ( void   ) 

Definition at line 668 of file enum.c.

References ast_enum_init().

00669 {
00670    return ast_enum_init();
00671 }

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 
)

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)
record The position of required RR in the answer list

Definition at line 390 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, 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.

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

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.

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 554 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, LOG_DEBUG, enum_context::naptrinput, enum_search::next, option_debug, s, enum_context::tech, enum_context::techlen, enum_search::toplev, toplevs, enum_context::txt, txt_callback(), and enum_context::txtlen.

00555 {
00556    struct enum_context context;
00557    char tmp[259 + 512];
00558    char naptrinput[512] = "+";
00559    int pos = strlen(number) - 1;
00560    int newpos = 0;
00561    int ret = -1;
00562    struct enum_search *s = NULL;
00563    int version = -1;
00564 
00565    strncat(naptrinput, number, sizeof(naptrinput) - 2);
00566 
00567    context.naptrinput = naptrinput;
00568    context.dst = dst;
00569    context.dstlen = dstlen;
00570    context.tech = tech;
00571    context.techlen = techlen;
00572    context.txt = txt;
00573    context.txtlen = txtlen;
00574 
00575    if (pos > 128)
00576       pos = 128;
00577    while (pos >= 0) {
00578       tmp[newpos++] = number[pos--];
00579       tmp[newpos++] = '.';
00580    }
00581 
00582    if (chan && ast_autoservice_start(chan) < 0)
00583       return -1;
00584 
00585    for (;;) {
00586       ast_mutex_lock(&enumlock);
00587       if (version != enumver) {
00588          /* Ooh, a reload... */
00589          s = toplevs;
00590          version = enumver;
00591       } else {
00592          s = s->next;
00593       }
00594       if (s) {
00595          ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos);
00596       }
00597       ast_mutex_unlock(&enumlock);
00598       if (!s)
00599          break;
00600 
00601       ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback);
00602       if (ret > 0)
00603          break;
00604    }
00605    if (ret < 0) {
00606       if (option_debug > 1)
00607          ast_log(LOG_DEBUG, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno));
00608       ret = 0;
00609    }
00610    if (chan)
00611       ret |= ast_autoservice_stop(chan);
00612    return ret;
00613 }


Generated on Wed Aug 15 01:25:07 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3