Fri Sep 29 11:14:02 2006

Asterisk developer's documentation


enum.c File Reference

ENUM Support for Asterisk. More...

#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.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)
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)
 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 *dst, int dstlen, char *tech, int techlen, char *txt, int txtlen)
 Lookup DNS TXT record (used by app TXTCIDnum.
 AST_MUTEX_DEFINE_STATIC (enumlock)
static int enum_callback (void *context, char *answer, int len, char *fullanswer)
static struct enum_searchenum_newtoplev (char *s)
static unsigned int parse_ie (unsigned char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen)
static int parse_naptr (unsigned char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, unsigned char *naptrinput)
static int txt_callback (void *context, char *answer, int len, char *fullanswer)

Variables

naptr __packed__
static int enumver = 0
static struct enum_searchtoplevs


Detailed Description

ENUM Support for Asterisk.

Definition in file enum.c.


Define Documentation

#define ENUMLOOKUP_OPTIONS_COUNT   1

Definition at line 282 of file enum.c.

Referenced by ast_get_enum(), and enum_callback().

#define TOPLEV   "e164.arpa."

Definition at line 65 of file enum.c.

Referenced by ast_enum_init().


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 }

AST_MUTEX_DEFINE_STATIC ( enumlock   ) 

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

Definition at line 338 of file enum.c.

References ast_log(), ast_strlen_zero(), enum_context::dst, enum_context::dstlen, ENUMLOOKUP_OPTIONS_COUNT, LOG_WARNING, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_context::options, parse_naptr(), enum_context::position, realloc, 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().

00339 {
00340        struct enum_context *c = (struct enum_context *)context;
00341        void *p = NULL;
00342        int res;
00343 
00344        res = parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput);
00345 
00346        if (res < 0) {
00347       ast_log(LOG_WARNING, "Failed to parse naptr :(\n");
00348       return -1;
00349        } else if (res > 0 && !ast_strlen_zero(c->dst)){ /* ok, we got needed NAPTR */
00350                if (c->options & ENUMLOOKUP_OPTIONS_COUNT){ /* counting RRs */
00351                        c->position++;
00352                        snprintf(c->dst, c->dstlen, "%d", c->position);
00353                } else  {
00354                        p = realloc(c->naptr_rrs, sizeof(struct enum_naptr_rr)*(c->naptr_rrs_count+1));
00355                        if (p) {
00356                                c->naptr_rrs = (struct enum_naptr_rr*)p;
00357                                memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(struct naptr));
00358                                c->naptr_rrs[c->naptr_rrs_count].result = strdup(c->dst);
00359                                c->naptr_rrs[c->naptr_rrs_count].tech = strdup(c->tech);
00360                                c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count;
00361                                c->naptr_rrs_count++;
00362                        }
00363                        c->dst[0] = 0;
00364                }
00365                return 0;
00366    }
00367 
00368        if (c->options & ENUMLOOKUP_OPTIONS_COUNT)  { /* counting RRs */
00369                snprintf(c->dst, c->dstlen, "%d", c->position);
00370        }
00371 
00372    return 0;
00373 }

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

Definition at line 610 of file enum.c.

References malloc.

Referenced by ast_enum_init().

00611 {
00612    struct enum_search *tmp;
00613 
00614    tmp = malloc(sizeof(struct enum_search));
00615    if (tmp) {
00616       memset(tmp, 0, sizeof(struct enum_search));
00617       ast_copy_string(tmp->toplev, s, sizeof(tmp->toplev));
00618    }
00619    return tmp;
00620 }

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

Definition at line 83 of file enum.c.

References ast_log(), and LOG_WARNING.

Referenced by parse_naptr().

00084 {
00085    unsigned int len, olen;
00086 
00087    len = olen = (unsigned int) src[0];
00088    src++;
00089    srclen--;
00090 
00091    if (len > srclen) {
00092       ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %d characters, got %d\n", len, srclen);
00093       return -1;
00094    }
00095 
00096    if (len > maxdatalen)
00097       len = maxdatalen;
00098    memcpy(data, src, len);
00099 
00100    return olen + 1;
00101 }

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

Definition at line 104 of file enum.c.

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

Referenced by enum_callback().

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

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

Definition at line 306 of file enum.c.

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

Referenced by ast_get_txt().

00307 {
00308    struct enum_context *c = (struct enum_context *)context;
00309 
00310    if (answer == NULL) {
00311       c->txt = NULL;
00312       c->txtlen = 0;
00313       return 0;
00314    }
00315 
00316    /* skip over first byte, as for some reason it's a vertical tab character */
00317    answer += 1;
00318    len -= 1;
00319 
00320    /* answer is not null-terminated, but should be */
00321        /* this is safe to do, as answer has extra bytes on the end we can
00322            safely overwrite with a null */
00323    answer[len] = '\0';
00324    /* now increment len so that len includes the null, so that we can
00325       compare apples to apples */
00326    len +=1;
00327 
00328    /* finally, copy the answer into c->txt */
00329    ast_copy_string(c->txt, answer, len < c->txtlen ? len : (c->txtlen));
00330 
00331    /* just to be safe, let's make sure c->txt is null terminated */
00332    c->txt[(c->txtlen)-1] = '\0';
00333 
00334    return 1;
00335 }


Variable Documentation

struct naptr __packed__

int enumver = 0 [static]

Definition at line 73 of file enum.c.

Referenced by ast_enum_init(), and ast_get_txt().

struct enum_search * toplevs [static]

Referenced by ast_enum_init(), ast_get_enum(), and ast_get_txt().


Generated on Fri Sep 29 11:14:02 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7