Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:31 2007

Asterisk developer's documentation :: Codename Pineapple


enum.h File Reference


Detailed Description

DNS and ENUM functions.

Definition in file enum.h.

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


Function Documentation

int ast_enum_init void   ) 
 

Initialize the ENUM support subsystem.

Definition at line 628 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, s, TOPLEV, toplevs, and ast_variable::value.

Referenced by ast_enum_reload().

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

int ast_enum_reload void   ) 
 

Definition at line 669 of file enum.c.

References ast_enum_init().

00670 {
00671    return ast_enum_init();
00672 }

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.

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_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enum_callback(), ENUMLOOKUP_OPTIONS_COUNT, LOG_DEBUG, enum_context::naptrinput, s, 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       if (option_debug)
00498          ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
00499       strcpy(dst, "0");
00500       ret = 0;
00501    }
00502 
00503    if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00504       /* sort array by NAPTR order/preference */
00505       for (k = 0; k < context.naptr_rrs_count; k++) {
00506          for (i = 0; i < context.naptr_rrs_count; i++) {
00507             /* use order first and then preference to compare */
00508             if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
00509                   && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00510                || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
00511                   && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00512                z = context.naptr_rrs[k].sort_pos;
00513                context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00514                context.naptr_rrs[i].sort_pos = z;
00515                continue;
00516             }
00517             if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
00518                if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
00519                      && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00520                   || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
00521                      && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00522                   z = context.naptr_rrs[k].sort_pos;
00523                   context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00524                   context.naptr_rrs[i].sort_pos = z;
00525                }
00526             }
00527          }
00528       }
00529       for (k = 0; k < context.naptr_rrs_count; k++) {
00530          if (context.naptr_rrs[k].sort_pos == context.position-1) {
00531             ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
00532             ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
00533             break;
00534          }
00535       }
00536    } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00537       context.dst[0] = 0;
00538    }
00539    if (chan)
00540       ret |= ast_autoservice_stop(chan);
00541 
00542    for (k = 0; k < context.naptr_rrs_count; k++) {
00543       free(context.naptr_rrs[k].result);
00544       free(context.naptr_rrs[k].tech);
00545    }
00546 
00547    free(context.naptr_rrs);
00548 
00549    return ret;
00550 }

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 555 of file enum.c.

References ast_autoservice_start(), ast_mutex_lock(), context, enum_context::naptrinput, s, and toplevs.

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


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen