Sat Sep 16 07:28:17 2006

Asterisk developer's documentation


enum.h File Reference

DNS and ENUM functions. More...

#include "asterisk/channel.h"

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 623 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, s, TOPLEV, toplevs, and ast_variable::value.

Referenced by ast_enum_reload(), and main().

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

int ast_enum_reload ( void   ) 

Definition at line 664 of file enum.c.

References ast_enum_init().

Referenced by ast_module_reload(), and main().

00665 {
00666    return ast_enum_init();
00667 }

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_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enum_callback(), ENUMLOOKUP_OPTIONS_COUNT, LOG_DEBUG, enum_context::naptrinput, s, 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/tech */
00489       for (k = 0; k < context.naptr_rrs_count; k++) {
00490          for (i = 0; i < context.naptr_rrs_count; i++) {
00491             /* Compare by order first. */
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             } else if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
00500                /* Order is the same, so sort by preference next */
00501                if (ntohs(context.naptr_rrs[k].naptr.pref) == ntohs(context.naptr_rrs[i].naptr.pref)) {
00502                   /* Preference is the same, so sort by tech */
00503                   if ((strcmp(context.naptr_rrs[k].tech, context.naptr_rrs[i].tech) < 0
00504                         && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00505                      || (strcmp(context.naptr_rrs[k].tech, context.naptr_rrs[i].tech) > 0
00506                         && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)) {
00507                      z = context.naptr_rrs[k].sort_pos;
00508                      context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00509                      context.naptr_rrs[i].sort_pos = z;
00510                   }
00511                } else if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
00512                      && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00513                   || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
00514                      && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00515                   z = context.naptr_rrs[k].sort_pos;
00516                   context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00517                   context.naptr_rrs[i].sort_pos = z;
00518                }
00519             }
00520          }
00521       }
00522       for (k = 0; k < context.naptr_rrs_count; k++) {
00523          if (context.naptr_rrs[k].sort_pos == context.position - 1) {
00524             ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
00525             ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
00526             break;
00527          }
00528       }
00529    } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00530       context.dst[0] = 0;
00531    }
00532 
00533    if (chan)
00534       ret |= ast_autoservice_stop(chan);
00535 
00536    for (k=0; k<context.naptr_rrs_count; k++) {
00537       free(context.naptr_rrs[k].result);
00538       free(context.naptr_rrs[k].tech);
00539    }
00540 
00541    free(context.naptr_rrs);
00542 
00543    return ret;
00544 }

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

References ast_autoservice_start(), ast_autoservice_stop(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enumver, LOG_DEBUG, enum_context::naptrinput, s, toplevs, and txt_callback().

Referenced by function_txtcidname(), and txtcidname_exec().

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


Generated on Sat Sep 16 07:28:17 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7