Tue Sep 30 01:19:57 2008

Asterisk developer's documentation


enum.c File Reference

ENUM Support for Asterisk. More...

#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <regex.h>
#include <unistd.h>
#include <errno.h>
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/enum.h"
#include "asterisk/dns.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"

Include dependency graph for enum.c:

Go to the source code of this file.

Data Structures

struct  enum_context
struct  enum_naptr_rr
struct  enum_search
struct  naptr

Defines

#define ENUMLOOKUP_OPTIONS_COUNT   1
#define TOPLEV   "e164.arpa."

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 *dst, int dstlen, char *tech, int techlen, char *suffix, char *options, unsigned int record)
 ENUM lookup.
int ast_get_txt (struct ast_channel *chan, const char *number, char *dst, int dstlen, char *tech, int techlen, char *txt, int txtlen)
 Get TXT record from DNS. Really has nothing to do with enum, but anyway...
 AST_MUTEX_DEFINE_STATIC (enumlock)
static int enum_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer)
 Callback from ENUM lookup function.
static struct enum_searchenum_newtoplev (char *s)
 Add enum tree to linked list.
static unsigned int parse_ie (char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen)
 Parse NAPTR record information elements.
static int parse_naptr (char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, char *naptrinput)
 Parse DNS NAPTR record used in ENUM ---.
static int txt_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer)
 Callback for TXT record lookup.

Variables

struct naptr __packed__
static int enumver
static struct enum_searchtoplevs


Detailed Description

ENUM Support for Asterisk.

Author:
Mark Spencer <markster@digium.com>
Enum standards

Possible improvement
Todo:
Implement a caching mechanism for multile enum lookups

Definition in file enum.c.


Define Documentation

#define ENUMLOOKUP_OPTIONS_COUNT   1

Definition at line 297 of file enum.c.

Referenced by ast_get_enum(), and enum_callback().

#define TOPLEV   "e164.arpa."

The IETF Enum standard root, managed by the ITU

Definition at line 80 of file enum.c.

Referenced by ast_enum_init().


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.

Referenced by ast_enum_reload(), and main().

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 
)

ENUM lookup.

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

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, errno, 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 function_enum().

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 
)

Get TXT record from DNS. Really has nothing to do with enum, but anyway...

Lookup DNS TXT record (used by app TXTCIDnum.

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, errno, 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.

Referenced by function_txtcidname().

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 }

AST_MUTEX_DEFINE_STATIC ( enumlock   ) 

static int enum_callback ( void *  context,
unsigned char *  answer,
int  len,
unsigned char *  fullanswer 
) [static]

Callback from ENUM lookup function.

Definition at line 353 of file enum.c.

References ast_log(), ast_realloc, ast_strlen_zero(), enum_context::dst, enum_context::dstlen, ENUMLOOKUP_OPTIONS_COUNT, LOG_WARNING, enum_naptr_rr::naptr, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_context::options, parse_naptr(), enum_context::position, enum_naptr_rr::result, enum_naptr_rr::sort_pos, strdup, enum_naptr_rr::tech, enum_context::tech, and enum_context::techlen.

Referenced by ast_get_enum().

00354 {
00355    struct enum_context *c = context;
00356    void *p = NULL;
00357    int res;
00358 
00359    res = parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput);
00360 
00361    if (res < 0) {
00362       ast_log(LOG_WARNING, "Failed to parse naptr :(\n");
00363       return -1;
00364    } else if (res > 0 && !ast_strlen_zero(c->dst)){ /* ok, we got needed NAPTR */
00365       if (c->options & ENUMLOOKUP_OPTIONS_COUNT){ /* counting RRs */
00366          c->position++;
00367          snprintf(c->dst, c->dstlen, "%d", c->position);
00368       } else  {
00369          if ((p = ast_realloc(c->naptr_rrs, sizeof(*c->naptr_rrs) * (c->naptr_rrs_count + 1)))) {
00370             c->naptr_rrs = p;
00371             memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(c->naptr_rrs->naptr));
00372             c->naptr_rrs[c->naptr_rrs_count].result = strdup(c->dst);
00373             c->naptr_rrs[c->naptr_rrs_count].tech = strdup(c->tech);
00374             c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count;
00375             c->naptr_rrs_count++;
00376          }
00377          c->dst[0] = 0;
00378       }
00379       return 0;
00380    }
00381 
00382    if (c->options & ENUMLOOKUP_OPTIONS_COUNT)   { /* counting RRs */
00383       snprintf(c->dst, c->dstlen, "%d", c->position);
00384    }
00385 
00386    return 0;
00387 }

static struct enum_search* enum_newtoplev ( char *  s  )  [static, read]

Add enum tree to linked list.

Definition at line 616 of file enum.c.

References ast_calloc, and enum_search::toplev.

Referenced by ast_enum_init().

00617 {
00618    struct enum_search *tmp;
00619 
00620    if ((tmp = ast_calloc(1, sizeof(*tmp)))) {      
00621       ast_copy_string(tmp->toplev, s, sizeof(tmp->toplev));
00622    }
00623    return tmp;
00624 }

static unsigned int parse_ie ( char *  data,
unsigned int  maxdatalen,
unsigned char *  src,
unsigned int  srclen 
) [static]

Parse NAPTR record information elements.

Definition at line 98 of file enum.c.

References ast_log(), len, and LOG_WARNING.

Referenced by parse_naptr().

00099 {
00100    unsigned int len, olen;
00101 
00102    len = olen = (unsigned int) src[0];
00103    src++;
00104    srclen--;
00105 
00106    if (len > srclen) {
00107       ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %d characters, got %d\n", len, srclen);
00108       return -1;
00109    }
00110 
00111    if (len > maxdatalen)
00112       len = maxdatalen;
00113    memcpy(data, src, len);
00114 
00115    return olen + 1;
00116 }

static int parse_naptr ( char *  dst,
int  dstsize,
char *  tech,
int  techsize,
unsigned char *  answer,
int  len,
char *  naptrinput 
) [static]

Parse DNS NAPTR record used in ENUM ---.

Definition at line 119 of file enum.c.

References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, and parse_ie().

Referenced by enum_callback().

00120 {
00121    char tech_return[80];
00122    unsigned char *oanswer = answer;
00123    char flags[512] = "";
00124    char services[512] = "";
00125    char *p;
00126    char regexp[512] = "";
00127    char repl[512] = "";
00128    char temp[512] = "";
00129    char delim;
00130    char *delim2;
00131    char *pattern, *subst, *d;
00132    int res;
00133    int regexp_len, size, backref;
00134    int d_len = sizeof(temp) - 1;
00135    regex_t preg;
00136    regmatch_t pmatch[9];
00137 
00138    tech_return[0] = '\0';
00139 
00140    dst[0] = '\0';
00141 
00142    if (len < sizeof(struct naptr)) {
00143       ast_log(LOG_WARNING, "NAPTR record length too short\n");
00144       return -1;
00145    }
00146    answer += sizeof(struct naptr);
00147    len -= sizeof(struct naptr);
00148    if ((res = parse_ie(flags, sizeof(flags) - 1, answer, len)) < 0) {
00149       ast_log(LOG_WARNING, "Failed to get flags from NAPTR record\n");
00150       return -1;
00151    } else {
00152       answer += res;
00153       len -= res;
00154    }
00155    if ((res = parse_ie(services, sizeof(services) - 1, answer, len)) < 0) {
00156       ast_log(LOG_WARNING, "Failed to get services from NAPTR record\n");
00157       return -1;
00158    } else {
00159       answer += res;
00160       len -= res;
00161    }
00162    if ((res = parse_ie(regexp, sizeof(regexp) - 1, answer, len)) < 0) {
00163       ast_log(LOG_WARNING, "Failed to get regexp from NAPTR record\n");
00164       return -1;
00165    } else {
00166       answer += res;
00167       len -= res;
00168    }
00169 
00170    if ((res = dn_expand(oanswer, answer + len, answer, repl, sizeof(repl) - 1)) < 0) {
00171       ast_log(LOG_WARNING, "Failed to expand hostname\n");
00172       return -1;
00173    }
00174 
00175    if (option_debug > 2)   /* Advanced NAPTR debugging */
00176       ast_log(LOG_DEBUG, "NAPTR input='%s', flags='%s', services='%s', regexp='%s', repl='%s'\n",
00177          naptrinput, flags, services, regexp, repl);
00178 
00179    if (tolower(flags[0]) != 'u') {
00180       ast_log(LOG_WARNING, "NAPTR Flag must be 'U' or 'u'.\n");
00181       return -1;
00182    }
00183 
00184    p = strstr(services, "e2u+");
00185    if (p == NULL)
00186       p = strstr(services, "E2U+");
00187    if (p){
00188       p = p + 4;
00189       if (strchr(p, ':')){
00190          p = strchr(p, ':') + 1;
00191       }
00192       ast_copy_string(tech_return, p, sizeof(tech_return));
00193    } else {
00194 
00195       p = strstr(services, "+e2u");
00196       if (p == NULL)
00197          p = strstr(services, "+E2U");
00198       if (p) {
00199          *p = 0;
00200          p = strchr(services, ':');
00201          if (p)
00202             *p = 0;
00203          ast_copy_string(tech_return, services, sizeof(tech_return));
00204       }
00205    }
00206 
00207    /* DEDBUGGING STUB
00208    ast_copy_string(regexp, "!^\\+43(.*)$!\\1@bla.fasel!", sizeof(regexp) - 1);
00209    */
00210 
00211    regexp_len = strlen(regexp);
00212    if (regexp_len < 7) {
00213       ast_log(LOG_WARNING, "Regex too short to be meaningful.\n");
00214       return -1;
00215    }
00216 
00217 
00218    delim = regexp[0];
00219    delim2 = strchr(regexp + 1, delim);
00220    if ((delim2 == NULL) || (regexp[regexp_len-1] != delim)) {
00221       ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n",regexp);
00222       return -1;
00223    }
00224 
00225    pattern = regexp + 1;
00226    *delim2 = 0;
00227    subst   = delim2 + 1;
00228    regexp[regexp_len-1] = 0;
00229 
00230 /*
00231  * now do the regex wizardry.
00232  */
00233 
00234    if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) {
00235       ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n",regexp);
00236       return -1;
00237    }
00238 
00239    if (preg.re_nsub > 9) {
00240       ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n");
00241       regfree(&preg);
00242       return -1;
00243    }
00244 
00245    if (regexec(&preg, naptrinput, 9, pmatch, 0)) {
00246       ast_log(LOG_WARNING, "NAPTR Regex match failed.\n");
00247       regfree(&preg);
00248       return -1;
00249    }
00250    regfree(&preg);
00251 
00252    d = temp;
00253    d_len--;
00254    while (*subst && (d_len > 0)) {
00255       if ((subst[0] == '\\') && isdigit(subst[1]) && (pmatch[subst[1]-'0'].rm_so != -1)) {
00256          backref = subst[1]-'0';
00257          size = pmatch[backref].rm_eo - pmatch[backref].rm_so;
00258          if (size > d_len) {
00259             ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n");
00260             return -1;
00261             }
00262          memcpy(d, naptrinput + pmatch[backref].rm_so, size);
00263          d += size;
00264          d_len -= size;
00265          subst += 2;
00266       } else if (isprint(*subst)) {
00267          *d++ = *subst++;
00268          d_len--;
00269       } else {
00270          ast_log(LOG_WARNING, "Error during regex substitution.\n");
00271          return -1;
00272       }
00273    }
00274    *d = 0;
00275    ast_copy_string(dst, temp, dstsize);
00276    dst[dstsize - 1] = '\0';
00277 
00278    if (*tech != '\0'){ /* check if it is requested NAPTR */
00279       if (!strncasecmp(tech, "ALL", techsize)){
00280          return 1; /* return or count any RR */
00281       }
00282       if (!strncasecmp(tech_return, tech, sizeof(tech_return)<techsize?sizeof(tech_return):techsize)){
00283          ast_copy_string(tech, tech_return, techsize);
00284          return 1; /* we got out RR */
00285       } else { /* go to the next RR in the DNS answer */
00286          return 0;
00287       }
00288    }
00289 
00290    /* tech was not specified, return first parsed RR */
00291    ast_copy_string(tech, tech_return, techsize);
00292 
00293    return 1;
00294 }

static int txt_callback ( void *  context,
unsigned char *  answer,
int  len,
unsigned char *  fullanswer 
) [static]

Callback for TXT record lookup.

Definition at line 321 of file enum.c.

References enum_context::txt, and enum_context::txtlen.

Referenced by ast_get_txt().

00322 {
00323    struct enum_context *c = (struct enum_context *)context;
00324 
00325    if (answer == NULL) {
00326       c->txt = NULL;
00327       c->txtlen = 0;
00328       return 0;
00329    }
00330 
00331    /* skip over first byte, as for some reason it's a vertical tab character */
00332    answer += 1;
00333    len -= 1;
00334 
00335    /* answer is not null-terminated, but should be */
00336    /* this is safe to do, as answer has extra bytes on the end we can
00337     * safely overwrite with a null */
00338    answer[len] = '\0';
00339    /* now increment len so that len includes the null, so that we can
00340     * compare apples to apples */
00341    len +=1;
00342 
00343    /* finally, copy the answer into c->txt */
00344    ast_copy_string(c->txt, (const char *) answer, len < c->txtlen ? len : (c->txtlen));
00345 
00346    /* just to be safe, let's make sure c->txt is null terminated */
00347    c->txt[(c->txtlen)-1] = '\0';
00348 
00349    return 1;
00350 }


Variable Documentation

struct naptr __packed__

int enumver [static]

Definition at line 88 of file enum.c.

struct enum_search * toplevs [static]


Generated on Tue Sep 30 01:19:57 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.6