Wed Jan 8 2020 09:50:11

Asterisk developer's documentation


enum.c File Reference

ENUM Support for Asterisk. More...

#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <ctype.h>
#include <regex.h>
#include "asterisk/enum.h"
#include "asterisk/dns.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"

Go to the source code of this file.

Data Structures

struct  ebl_context
 
struct  txt_context
 

Macros

#define ENUMLOOKUP_BLR_CC   0
 
#define ENUMLOOKUP_BLR_EBL   2
 
#define ENUMLOOKUP_BLR_TXT   1
 
#define ENUMLOOKUP_OPTIONS_COUNT   1
 
#define ENUMLOOKUP_OPTIONS_DIRECT   8
 
#define ENUMLOOKUP_OPTIONS_IENUM   4
 
#define ENUMLOOKUP_OPTIONS_ISN   2
 
#define T_EBL   65300
 

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, unsigned int record, struct enum_context **argcontext)
 Lookup entry in ENUM. More...
 
int ast_get_txt (struct ast_channel *chan, const char *number, char *txt, int txtlen, char *suffix)
 Lookup DNS TXT record (used by app TXTCIDnum) More...
 
static int blr_ebl (const char *cc, const char *suffix, char *separator, int sep_len, char *apex, int apex_len)
 Evaluate the I-ENUM branch as stored in an EBL record. More...
 
static int blr_txt (const char *cc, const char *suffix)
 Determine the branch location record as stored in a TXT record. More...
 
static int cclen (const char *number)
 Determine the length of a country code when given an E.164 string. More...
 
static int ebl_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer)
 Callback for EBL record lookup. More...
 
static int enum_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer)
 Callback from ENUM lookup function. More...
 
static unsigned int parse_ie (char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen)
 Parse NAPTR record information elements. More...
 
static int parse_naptr (unsigned char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, unsigned char *naptrinput)
 Parse DNS NAPTR record used in ENUM —. More...
 
static int private_enum_init (int reload)
 Initialize the ENUM support subsystem. More...
 
static int txt_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer)
 Callback for TXT record lookup, /ol version. More...
 

Variables

static int ebl_alg = ENUMLOOKUP_BLR_CC
 
static ast_mutex_t enumlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static char ienum_branchlabel [32] = "i"
 

Detailed Description

ENUM Support for Asterisk.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
  • Funding provided by nic.at
Enum standards
Possible improvement
Todo:

Implement a caching mechanism for multile enum lookups

The service type selection needs to be redone.

Definition in file enum.c.

Macro Definition Documentation

#define ENUMLOOKUP_BLR_CC   0

Definition at line 87 of file enum.c.

Referenced by ast_get_enum(), and private_enum_init().

#define ENUMLOOKUP_BLR_EBL   2

Definition at line 89 of file enum.c.

Referenced by ast_get_enum(), and private_enum_init().

#define ENUMLOOKUP_BLR_TXT   1

Definition at line 88 of file enum.c.

Referenced by ast_get_enum(), and private_enum_init().

#define ENUMLOOKUP_OPTIONS_COUNT   1

Definition at line 590 of file enum.c.

Referenced by ast_get_enum(), and enum_callback().

#define ENUMLOOKUP_OPTIONS_DIRECT   8

Definition at line 596 of file enum.c.

Referenced by ast_get_enum().

#define ENUMLOOKUP_OPTIONS_IENUM   4

Definition at line 594 of file enum.c.

Referenced by ast_get_enum().

#define ENUMLOOKUP_OPTIONS_ISN   2

Definition at line 592 of file enum.c.

Referenced by ast_get_enum().

#define T_EBL   65300

Definition at line 93 of file enum.c.

Referenced by blr_ebl().

Function Documentation

int ast_enum_init ( void  )

Definition at line 1006 of file enum.c.

References private_enum_init().

Referenced by main().

1007 {
1008  return private_enum_init(0);
1009 }
static int private_enum_init(int reload)
Initialize the ENUM support subsystem.
Definition: enum.c:968
int ast_enum_reload ( void  )

Definition at line 1011 of file enum.c.

References private_enum_init().

1012 {
1013  return private_enum_init(1);
1014 }
static int private_enum_init(int reload)
Initialize the ENUM support subsystem.
Definition: enum.c:968
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,
struct enum_context **  argcontext 
)

Lookup entry in ENUM.

Parameters
chanChannel
numberE164 number with or without the leading +
locationNumber returned (or SIP uri)
maxlocMax length
technologyTechnology (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 "ALL" string
maxtechMax length
suffixZone suffix (WARNING: No defaults here any more)
optionsOptions 'c' - Count number of NAPTR RR number - Position of the requested RR in the answer list 'u' - Full URI return (does not strip URI scheme) 'i' - Infrastructure ENUM lookup 's' - ISN based lookup 'd' - Direct DNS query
recordThe position of required RR in the answer list
argcontextArgument for caching results into an enum_context pointer (NULL is used for not caching)
Return values
1if found
0if not found
-1on hangup

Definition at line 632 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_calloc, ast_copy_string(), ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_search_dns(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), blr_ebl(), blr_txt(), cclen(), context, enum_context::count, enum_context::dst, enum_context::dstlen, enum_callback(), enumlock, ENUMLOOKUP_BLR_CC, ENUMLOOKUP_BLR_EBL, ENUMLOOKUP_BLR_TXT, ENUMLOOKUP_OPTIONS_COUNT, ENUMLOOKUP_OPTIONS_DIRECT, ENUMLOOKUP_OPTIONS_IENUM, ENUMLOOKUP_OPTIONS_ISN, errno, LOG_WARNING, enum_naptr_rr::naptr, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_context::options, naptr::order, enum_context::position, naptr::pref, enum_naptr_rr::result, enum_naptr_rr::sort_pos, enum_naptr_rr::tech, enum_context::tech, and enum_context::techlen.

Referenced by enum_query_read(), and function_enum().

633 {
634  struct enum_context *context;
635  char tmp[512];
636  char domain[256];
637  char left[128];
638  char middle[128];
639  char naptrinput[128];
640  char apex[128] = "";
641  int ret = -1;
642  /* for ISN rewrite */
643  char *p1 = NULL;
644  char *p2 = NULL;
645  char *p3 = NULL;
646  int k = 0;
647  int i = 0;
648  int z = 0;
649  int spaceleft = 0;
650  struct timeval time_start, time_end;
651 
652  if (ast_strlen_zero(suffix)) {
653  ast_log(LOG_WARNING, "ast_get_enum need a suffix parameter now.\n");
654  return -1;
655  }
656 
657  ast_debug(2, "num='%s', tech='%s', suffix='%s', options='%s', record=%u\n", number, tech, suffix, options, record);
658 
659 /*
660  We don't need that any more, that "n" preceding the number has been replaced by a flag
661  in the options paramter.
662  ast_copy_string(naptrinput, number, sizeof(naptrinput));
663 */
664 /*
665  * The "number" parameter includes a leading '+' if it's a full E.164 number (and not ISN)
666  * We need to preserve that as the regex inside NAPTRs expect the +.
667  *
668  * But for the domain generation, the '+' is a nuissance, so we get rid of it.
669 */
670  ast_copy_string(naptrinput, number[0] == 'n' ? number + 1 : number, sizeof(naptrinput));
671  if (number[0] == '+') {
672  number++;
673  }
674 
675  if (!(context = ast_calloc(1, sizeof(*context)))) {
676  return -1;
677  }
678 
679  if ((p3 = strchr(naptrinput, '*'))) {
680  *p3='\0';
681  }
682 
683  context->naptrinput = naptrinput; /* The number */
684  context->dst = dst; /* Return string */
685  context->dstlen = dstlen;
686  context->tech = tech;
687  context->techlen = techlen;
688  context->options = 0;
689  context->position = record > 0 ? record : 1;
690  context->count = 0;
691  context->naptr_rrs = NULL;
692  context->naptr_rrs_count = 0;
693 
694  /*
695  * Process options:
696  *
697  * c Return count, not URI
698  * i Use infrastructure ENUM
699  * s Do ISN transformation
700  * d Direct DNS query: no reversing.
701  *
702  */
703  if (options != NULL) {
704  if (strchr(options,'s')) {
705  context->options |= ENUMLOOKUP_OPTIONS_ISN;
706  } else if (strchr(options,'i')) {
707  context->options |= ENUMLOOKUP_OPTIONS_IENUM;
708  } else if (strchr(options,'d')) {
710  }
711  if (strchr(options,'c')) {
712  context->options |= ENUMLOOKUP_OPTIONS_COUNT;
713  }
714  if (strchr(number,'*')) {
715  context->options |= ENUMLOOKUP_OPTIONS_ISN;
716  }
717  }
718  ast_debug(2, "ENUM options(%s): pos=%d, options='%d'\n", options, context->position, context->options);
719  ast_debug(1, "n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n",
720  number, tech, suffix, context->options, context->position);
721 
722  /*
723  * This code does more than simple RFC3261 ENUM. All these rewriting
724  * schemes have in common that they build the FQDN for the NAPTR lookup
725  * by concatenating
726  * - a number which needs be flipped and "."-seperated (left)
727  * - some fixed string (middle)
728  * - an Apex. (apex)
729  *
730  * The RFC3261 ENUM is: left=full number, middle="", apex=from args.
731  * ISN: number = "middle*left", apex=from args
732  * I-ENUM: EBL parameters build the split, can change apex
733  * Direct: left="", middle=argument, apex=from args
734  *
735  */
736 
737  /* default: the whole number will be flipped, no middle domain component */
738  ast_copy_string(left, number, sizeof(left));
739  middle[0] = '\0';
740  /*
741  * I-ENUM can change the apex, thus we copy it
742  */
743  ast_copy_string(apex, suffix, sizeof(apex));
744  /* ISN rewrite */
745  if ((context->options & ENUMLOOKUP_OPTIONS_ISN) && (p1 = strchr(number, '*'))) {
746  *p1++ = '\0';
747  ast_copy_string(left, number, sizeof(left));
748  ast_copy_string(middle, p1, sizeof(middle) - 1);
749  strcat(middle, ".");
750  ast_debug(2, "ISN ENUM: left=%s, middle='%s'\n", left, middle);
751  /* Direct DNS lookup rewrite */
752  } else if (context->options & ENUMLOOKUP_OPTIONS_DIRECT) {
753  left[0] = 0; /* nothing to flip around */
754  ast_copy_string(middle, number, sizeof(middle) - 1);
755  strcat(middle, ".");
756  ast_debug(2, "DIRECT ENUM: middle='%s'\n", middle);
757  /* Infrastructure ENUM rewrite */
758  } else if (context->options & ENUMLOOKUP_OPTIONS_IENUM) {
759  int sdl = 0;
760  char cc[8];
761  char sep[256], n_apex[256];
762  int cc_len = cclen(number);
763  sdl = cc_len;
765  ast_copy_string(sep, ienum_branchlabel, sizeof(sep)); /* default */
767 
768  switch (ebl_alg) {
769  case ENUMLOOKUP_BLR_EBL:
770  ast_copy_string(cc, number, cc_len); /* cclen() never returns more than 3 */
771  sdl = blr_ebl(cc, suffix, sep, sizeof(sep) - 1, n_apex, sizeof(n_apex) - 1);
772 
773  if (sdl >= 0) {
774  ast_copy_string(apex, n_apex, sizeof(apex));
775  ast_debug(2, "EBL ENUM: sep=%s, apex='%s'\n", sep, n_apex);
776  } else {
777  sdl = cc_len;
778  }
779  break;
780  case ENUMLOOKUP_BLR_TXT:
781  ast_copy_string(cc, number, cc_len); /* cclen() never returns more than 3 */
782  sdl = blr_txt(cc, suffix);
783 
784  if (sdl < 0) {
785  sdl = cc_len;
786  }
787  break;
788 
789  case ENUMLOOKUP_BLR_CC: /* BLR is at the country-code level */
790  default:
791  sdl = cc_len;
792  break;
793  }
794 
795  if (sdl > strlen(number)) { /* Number too short for this sdl? */
796  ast_log(LOG_WARNING, "I-ENUM: subdomain location %d behind number %s\n", sdl, number);
797  ast_free(context);
798  return 0;
799  }
800  ast_copy_string(left, number + sdl, sizeof(left));
801 
803  ast_copy_string(middle, sep, sizeof(middle) - 1);
804  strcat(middle, ".");
806 
807  /* check the space we need for middle */
808  if ((sdl * 2 + strlen(middle) + 2) > sizeof(middle)) {
809  ast_log(LOG_WARNING, "ast_get_enum: not enough space for I-ENUM rewrite.\n");
810  ast_free(context);
811  return -1;
812  }
813 
814  p1 = middle + strlen(middle);
815  for (p2 = (char *) number + sdl - 1; p2 >= number; p2--) {
816  if (isdigit(*p2)) {
817  *p1++ = *p2;
818  *p1++ = '.';
819  }
820  }
821  *p1 = '\0';
822 
823  ast_debug(2, "I-ENUM: cclen=%d, left=%s, middle='%s', apex='%s'\n", cc_len, left, middle, apex);
824  }
825 
826  if (strlen(left) * 2 + 2 > sizeof(domain)) {
827  ast_log(LOG_WARNING, "string to long in ast_get_enum\n");
828  ast_free(context);
829  return -1;
830  }
831 
832  /* flip left into domain */
833  p1 = domain;
834  for (p2 = left + strlen(left); p2 >= left; p2--) {
835  if (isdigit(*p2)) {
836  *p1++ = *p2;
837  *p1++ = '.';
838  }
839  }
840  *p1 = '\0';
841 
842  if (chan && ast_autoservice_start(chan) < 0) {
843  ast_free(context);
844  return -1;
845  }
846 
847  spaceleft = sizeof(tmp) - 2;
848  ast_copy_string(tmp, domain, spaceleft);
849  spaceleft -= strlen(domain);
850 
851  if (*middle) {
852  strncat(tmp, middle, spaceleft);
853  spaceleft -= strlen(middle);
854  }
855 
856  strncat(tmp,apex,spaceleft);
857  time_start = ast_tvnow();
858  ret = ast_search_dns(context, tmp, C_IN, T_NAPTR, enum_callback);
859  time_end = ast_tvnow();
860 
861  ast_debug(2, "profiling: %s, %s, %" PRIi64 " ms\n",
862  (ret == 0) ? "OK" : "FAIL", tmp, ast_tvdiff_ms(time_end, time_start));
863 
864  if (ret < 0) {
865  ast_debug(1, "No such number found: %s (%s)\n", tmp, strerror(errno));
866  strcpy(dst, "0");
867  ret = 0;
868  }
869 
870  if (context->naptr_rrs_count >= context->position && ! (context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
871  /* sort array by NAPTR order/preference */
872  for (k = 0; k < context->naptr_rrs_count; k++) {
873  for (i = 0; i < context->naptr_rrs_count; i++) {
874  /* use order first and then preference to compare */
875  if ((ntohs(context->naptr_rrs[k].naptr.order) < ntohs(context->naptr_rrs[i].naptr.order)
876  && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
877  || (ntohs(context->naptr_rrs[k].naptr.order) > ntohs(context->naptr_rrs[i].naptr.order)
878  && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)) {
879  z = context->naptr_rrs[k].sort_pos;
880  context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
881  context->naptr_rrs[i].sort_pos = z;
882  continue;
883  }
884  if (ntohs(context->naptr_rrs[k].naptr.order) == ntohs(context->naptr_rrs[i].naptr.order)) {
885  if ((ntohs(context->naptr_rrs[k].naptr.pref) < ntohs(context->naptr_rrs[i].naptr.pref)
886  && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
887  || (ntohs(context->naptr_rrs[k].naptr.pref) > ntohs(context->naptr_rrs[i].naptr.pref)
888  && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)) {
889  z = context->naptr_rrs[k].sort_pos;
890  context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
891  context->naptr_rrs[i].sort_pos = z;
892  }
893  }
894  }
895  }
896  for (k = 0; k < context->naptr_rrs_count; k++) {
897  if (context->naptr_rrs[k].sort_pos == context->position - 1) {
898  ast_copy_string(context->dst, context->naptr_rrs[k].result, dstlen);
899  ast_copy_string(context->tech, context->naptr_rrs[k].tech, techlen);
900  break;
901  }
902  }
903  } else if (!(context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
904  context->dst[0] = 0;
905  } else if ((context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
906  snprintf(context->dst, context->dstlen, "%d", context->count);
907  }
908 
909  if (chan) {
910  ret |= ast_autoservice_stop(chan);
911  }
912 
913  if (!argcontext) {
914  for (k = 0; k < context->naptr_rrs_count; k++) {
915  ast_free(context->naptr_rrs[k].result);
916  ast_free(context->naptr_rrs[k].tech);
917  }
918  ast_free(context->naptr_rrs);
919  ast_free(context);
920  } else {
921  *argcontext = context;
922  }
923 
924  return ret;
925 }
static int enum_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Callback from ENUM lookup function.
Definition: enum.c:599
#define ENUMLOOKUP_OPTIONS_COUNT
Definition: enum.c:590
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
int count
Definition: enum.h:49
static char ienum_branchlabel[32]
Definition: enum.c:85
struct enum_naptr_rr * naptr_rrs
Definition: enum.h:51
#define LOG_WARNING
Definition: logger.h:144
int ast_search_dns(void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Perform DNS lookup (used by DNS, enum and SRV lookups)
Definition: dns.c:259
static int cclen(const char *number)
Determine the length of a country code when given an E.164 string.
Definition: enum.c:110
static ast_mutex_t enumlock
Definition: enum.c:95
static int ebl_alg
Definition: enum.c:90
unsigned short pref
Definition: enum.h:30
int dstlen
Definition: enum.h:42
int position
Definition: enum.h:48
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define ENUMLOOKUP_OPTIONS_DIRECT
Definition: enum.c:596
#define ENUMLOOKUP_BLR_CC
Definition: enum.c:87
Number structure.
Definition: app_followme.c:109
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ENUMLOOKUP_BLR_EBL
Definition: enum.c:89
int techlen
Definition: enum.h:44
char * dst
Definition: enum.h:41
unsigned short order
Definition: enum.h:29
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct naptr naptr
Definition: enum.h:34
char * naptrinput
Definition: enum.h:47
char * tech
Definition: enum.h:36
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define ast_free(a)
Definition: astmm.h:97
char * result
Definition: enum.h:35
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int naptr_rrs_count
Definition: enum.h:52
#define ENUMLOOKUP_OPTIONS_IENUM
Definition: enum.c:594
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char * tech
Definition: enum.h:43
int sort_pos
Definition: enum.h:37
#define ENUMLOOKUP_OPTIONS_ISN
Definition: enum.c:592
int options
Definition: enum.h:50
#define ENUMLOOKUP_BLR_TXT
Definition: enum.c:88
static int blr_txt(const char *cc, const char *suffix)
Determine the branch location record as stored in a TXT record.
Definition: enum.c:195
static int blr_ebl(const char *cc, const char *suffix, char *separator, int sep_len, char *apex, int apex_len)
Evaluate the I-ENUM branch as stored in an EBL record.
Definition: enum.c:324
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_get_txt ( struct ast_channel chan,
const char *  number,
char *  txt,
int  maxtxt,
char *  suffix 
)

Lookup DNS TXT record (used by app TXTCIDnum)

Really has nothing to do with enum, but anyway... Actually, there is now an internet-draft which describes how callerID should be stored in ENUM domains: draft-ietf-enum-cnam-04.txt The algorithm implemented here will thus be obsolete soon.

Parameters
chanChannel
numberE164 number with or without the leading +
txtText string (return value)
maxtxtMax length of "txt"
suffixZone suffix
Version
1.6.1 new suffix parameter to take into account caller ids that aren't in e164.arpa
1.6.1 removed parameters location, maxloc, technology, maxtech as all the information is stored the txt string

Definition at line 927 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_debug, errno, and txt_context::txt.

Referenced by function_txtcidname().

928 {
929  struct txt_context context;
930  char tmp[259 + 512];
931  int pos = strlen(number) - 1;
932  int newpos = 0;
933  int ret = -1;
934 
935  ast_debug(4, "ast_get_txt: Number = '%s', suffix = '%s'\n", number, suffix);
936 
937  if (chan && ast_autoservice_start(chan) < 0) {
938  return -1;
939  }
940 
941  if (pos > 128) {
942  pos = 128;
943  }
944 
945  while (pos >= 0) {
946  if (isdigit(number[pos])) {
947  tmp[newpos++] = number[pos];
948  tmp[newpos++] = '.';
949  }
950  pos--;
951  }
952 
953  ast_copy_string(&tmp[newpos], suffix, sizeof(tmp) - newpos);
954 
955  if (ret < 0) {
956  ast_debug(2, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno));
957  ret = 0;
958  } else {
960  }
961  if (chan) {
962  ret |= ast_autoservice_stop(chan);
963  }
964  return ret;
965 }
char txt[1024]
Definition: enum.c:140
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
int txtlen
Definition: enum.c:141
Number structure.
Definition: app_followme.c:109
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
int errno
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int blr_ebl ( const char *  cc,
const char *  suffix,
char *  separator,
int  sep_len,
char *  apex,
int  apex_len 
)
static

Evaluate the I-ENUM branch as stored in an EBL record.

Definition at line 324 of file enum.c.

References ebl_context::apex, ast_copy_string(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_search_dns(), ast_verb, ebl_callback(), enumlock, LOG_WARNING, ebl_context::pos, ebl_context::separator, and T_EBL.

Referenced by ast_get_enum().

325 {
326  struct ebl_context context;
327  char domain[128] = "";
328  char *p1,*p2;
329  int ret;
330 
332 
333  ast_verb(4, "blr_ebl() cc='%s', suffix='%s', c_bl='%s'\n", cc, suffix, ienum_branchlabel);
334 
335  if (sizeof(domain) < (strlen(cc) * 2 + strlen(ienum_branchlabel) + strlen(suffix) + 2)) {
337  ast_log(LOG_WARNING, "ERROR: string sizing in blr_EBL.\n");
338  return -1;
339  }
340 
341  p1 = domain + snprintf(domain, sizeof(domain), "%s.", ienum_branchlabel);
343 
344  for (p2 = (char *) cc + strlen(cc) - 1; p2 >= cc; p2--) {
345  if (isdigit(*p2)) {
346  *p1++ = *p2;
347  *p1++ = '.';
348  }
349  }
350  strcat(p1, suffix);
351 
352  ast_verb(4, "blr_ebl() FQDN for EBL record: %s, cc was %s\n", domain, cc);
353 
354  ret = ast_search_dns(&context, domain, C_IN, T_EBL, ebl_callback);
355  if (ret > 0) {
356  ret = context.pos;
357 
358  if ((ret >= 0) && (ret < 20)) {
359  ast_verb(3, "blr_txt() BLR EBL record for %s is %d/%s/%s)\n", cc, ret, context.separator, context.apex);
362  return ret;
363  }
364  }
365  ast_verb(3, "blr_txt() BLR EBL record for %s not found (apex: %s)\n", cc, suffix);
366  return -1;
367 }
static char ienum_branchlabel[32]
Definition: enum.c:85
int apex_len
Definition: enum.c:246
#define LOG_WARNING
Definition: logger.h:144
int ast_search_dns(void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Perform DNS lookup (used by DNS, enum and SRV lookups)
Definition: dns.c:259
static ast_mutex_t enumlock
Definition: enum.c:95
#define ast_mutex_lock(a)
Definition: lock.h:155
char separator[256]
Definition: enum.c:243
#define ast_verb(level,...)
Definition: logger.h:243
int sep_len
Definition: enum.c:244
char apex[256]
Definition: enum.c:245
#define T_EBL
Definition: enum.c:93
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int ebl_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Callback for EBL record lookup.
Definition: enum.c:250
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int blr_txt ( const char *  cc,
const char *  suffix 
)
static

Determine the branch location record as stored in a TXT record.

Definition at line 195 of file enum.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_search_dns(), ast_verb, enumlock, LOG_WARNING, txt_context::txt, and txt_callback().

Referenced by ast_get_enum().

196 {
197  struct txt_context context;
198  char domain[128] = "";
199  char *p1, *p2;
200  int ret;
201 
203 
204  ast_verb(4, "blr_txt() cc='%s', suffix='%s', c_bl='%s'\n", cc, suffix, ienum_branchlabel);
205 
206  if (sizeof(domain) < (strlen(cc) * 2 + strlen(ienum_branchlabel) + strlen(suffix) + 2)) {
208  ast_log(LOG_WARNING, "ERROR: string sizing in blr_txt.\n");
209  return -1;
210  }
211 
212  p1 = domain + snprintf(domain, sizeof(domain), "%s.", ienum_branchlabel);
214 
215  for (p2 = (char *) cc + strlen(cc) - 1; p2 >= cc; p2--) {
216  if (isdigit(*p2)) {
217  *p1++ = *p2;
218  *p1++ = '.';
219  }
220  }
221  strcat(p1, suffix);
222 
223  ast_verb(4, "blr_txt() FQDN for TXT record: %s, cc was %s\n", domain, cc);
224 
225  ret = ast_search_dns(&context, domain, C_IN, T_TXT, txt_callback);
226 
227  if (ret > 0) {
228  ret = atoi(context.txt);
229 
230  if ((ret >= 0) && (ret < 20)) {
231  ast_verb(3, "blr_txt() BLR TXT record for %s is %d (apex: %s)\n", cc, ret, suffix);
232  return ret;
233  }
234  }
235 
236  ast_verb(3, "blr_txt() BLR TXT record for %s not found (apex: %s)\n", cc, suffix);
237 
238  return -1;
239 }
static char ienum_branchlabel[32]
Definition: enum.c:85
#define LOG_WARNING
Definition: logger.h:144
int ast_search_dns(void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Perform DNS lookup (used by DNS, enum and SRV lookups)
Definition: dns.c:259
static ast_mutex_t enumlock
Definition: enum.c:95
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_verb(level,...)
Definition: logger.h:243
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int txt_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Callback for TXT record lookup, /ol version.
Definition: enum.c:145
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int cclen ( const char *  number)
static

Determine the length of a country code when given an E.164 string.

Definition at line 110 of file enum.c.

Referenced by ast_get_enum().

111 {
112  int cc;
113  char digits[3] = "";
114 
115  if (!number || (strlen(number) < 3)) {
116  return 0;
117  }
118 
119  strncpy(digits, number, 2);
120 
121  if (!sscanf(digits, "%30d", &cc)) {
122  return 0;
123  }
124 
125  if (cc / 10 == 1 || cc / 10 == 7)
126  return 1;
127 
128  if (cc == 20 || cc == 27 || (cc >= 30 && cc <= 34) || cc == 36 ||
129  cc == 39 || cc == 40 || cc == 41 || (cc >= 40 && cc <= 41) ||
130  (cc >= 43 && cc <= 49) || (cc >= 51 && cc <= 58) ||
131  (cc >= 60 && cc <= 66) || cc == 81 || cc == 82 || cc == 84 ||
132  cc == 86 || (cc >= 90 && cc <= 95) || cc == 98) {
133  return 2;
134  }
135 
136  return 3;
137 }
Number structure.
Definition: app_followme.c:109
static int ebl_callback ( void *  context,
unsigned char *  answer,
int  len,
unsigned char *  fullanswer 
)
static

Callback for EBL record lookup.

Definition at line 250 of file enum.c.

References ebl_context::apex, ebl_context::apex_len, ast_copy_string(), ast_log(), context, LOG_WARNING, ebl_context::pos, ebl_context::sep_len, and ebl_context::separator.

Referenced by blr_ebl().

251 {
252  struct ebl_context *c = context;
253  unsigned int i;
254 
255  c->pos = 0; /* default to empty */
256  c->separator[0] = 0;
257  c->sep_len = 0;
258  c->apex[0] = 0;
259  c->apex_len = 0;
260 
261  if (answer == NULL) {
262  return 0;
263  }
264 
265  /* draft-lendl-enum-branch-location-record-00
266  *
267  * 0 1 2 3 4 5 6 7
268  * +--+--+--+--+--+--+--+--+
269  * | POSITION |
270  * +--+--+--+--+--+--+--+--+
271  * / SEPARATOR /
272  * +--+--+--+--+--+--+--+--+
273  * / APEX /
274  * +--+--+--+--+--+--+--+--+
275  *
276  * where POSITION is a single byte, SEPARATOR is a <character-string>
277  * and APEX is a <domain-name>.
278  *
279  */
280 
281  c->pos = *answer++;
282  len -= 1;
283 
284  if ((c->pos > 15) || len < 2) { /* illegal packet */
285  ast_log(LOG_WARNING, "ebl_callback: malformed EBL record.\n");
286  return 0;
287  }
288 
289  i = *answer++;
290  len -= 1;
291  if (i > len) { /* illegal packet */
292  ast_log(LOG_WARNING, "ebl_callback: malformed EBL record.\n");
293  return 0;
294  }
295 
296  ast_copy_string(c->separator, (char *)answer, i + 1);
297  c->sep_len = i;
298 
299  answer += i;
300  len -= i;
301 
302  if ((i = dn_expand((unsigned char *)fullanswer, (unsigned char *)answer + len,
303  (unsigned char *)answer, c->apex, sizeof(c->apex) - 1)) < 0) {
304  ast_log(LOG_WARNING, "Failed to expand hostname\n");
305  return 0;
306  }
307  c->apex[i] = 0;
308  c->apex_len = i;
309 
310  return 1;
311 }
int apex_len
Definition: enum.c:246
#define LOG_WARNING
Definition: logger.h:144
char separator[256]
Definition: enum.c:243
unsigned char pos
Definition: enum.c:242
int sep_len
Definition: enum.c:244
char apex[256]
Definition: enum.c:245
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int enum_callback ( void *  context,
unsigned char *  answer,
int  len,
unsigned char *  fullanswer 
)
static

Callback from ENUM lookup function.

Definition at line 599 of file enum.c.

References ast_log(), ast_realloc, ast_strdup, ast_strlen_zero(), context, enum_context::count, 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_naptr_rr::result, enum_naptr_rr::sort_pos, enum_naptr_rr::tech, enum_context::tech, and enum_context::techlen.

Referenced by ast_get_enum().

600 {
601  struct enum_context *c = context;
602  void *p = NULL;
603  int res;
604 
605  res = parse_naptr((unsigned char *)c->dst, c->dstlen, c->tech, c->techlen, answer, len, (unsigned char *)c->naptrinput);
606 
607  if (res < 0) {
608  ast_log(LOG_WARNING, "Failed to parse naptr\n");
609  return -1;
610  } else if ((res == 0) && !ast_strlen_zero(c->dst)) { /* ok, we got needed NAPTR */
611  if (c->options & ENUMLOOKUP_OPTIONS_COUNT) { /* counting RRs */
612  c->count++;
613  snprintf(c->dst, c->dstlen, "%d", c->count);
614  } else {
615  if ((p = ast_realloc(c->naptr_rrs, sizeof(*c->naptr_rrs) * (c->naptr_rrs_count + 1)))) {
616  c->naptr_rrs = p;
617  memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(c->naptr_rrs->naptr));
621  c->naptr_rrs_count++;
622  }
623  c->dst[0] = 0;
624  }
625  return 0;
626  }
627 
628  return 0;
629 }
#define ENUMLOOKUP_OPTIONS_COUNT
Definition: enum.c:590
#define ast_strdup(a)
Definition: astmm.h:109
int count
Definition: enum.h:49
struct enum_naptr_rr * naptr_rrs
Definition: enum.h:51
#define LOG_WARNING
Definition: logger.h:144
int dstlen
Definition: enum.h:42
int techlen
Definition: enum.h:44
char * dst
Definition: enum.h:41
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct naptr naptr
Definition: enum.h:34
char * naptrinput
Definition: enum.h:47
char * tech
Definition: enum.h:36
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, unsigned char *naptrinput)
Parse DNS NAPTR record used in ENUM —.
Definition: enum.c:391
char * result
Definition: enum.h:35
#define ast_realloc(a, b)
Definition: astmm.h:103
int naptr_rrs_count
Definition: enum.h:52
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char * tech
Definition: enum.h:43
int sort_pos
Definition: enum.h:37
int options
Definition: enum.h:50
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 370 of file enum.c.

References ast_log(), len(), and LOG_WARNING.

Referenced by parse_naptr().

371 {
372  unsigned int len, olen;
373 
374  len = olen = (unsigned int) src[0];
375  src++;
376  srclen--;
377 
378  if (len > srclen) {
379  ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %u characters, got %u\n", len, srclen);
380  return -1;
381  }
382 
383  if (len > maxdatalen)
384  len = maxdatalen;
385  memcpy(data, src, len);
386 
387  return olen + 1;
388 }
#define LOG_WARNING
Definition: logger.h:144
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int parse_naptr ( unsigned char *  dst,
int  dstsize,
char *  tech,
int  techsize,
unsigned char *  answer,
int  len,
unsigned char *  naptrinput 
)
static

Parse DNS NAPTR record used in ENUM —.

Definition at line 391 of file enum.c.

References ARRAY_LEN, ast_copy_string(), ast_debug, ast_log(), LOG_WARNING, and parse_ie().

Referenced by enum_callback().

392 {
393  char tech_return[80];
394  char *oanswer = (char *)answer;
395  char flags[512] = "";
396  char services[512] = "";
397  char *p;
398  char regexp[512] = "";
399  char repl[512] = "";
400  char tempdst[512] = "";
401  char errbuff[512] = "";
402  char delim;
403  char *delim2;
404  char *pattern, *subst, *d;
405  int res;
406  int regexp_len, rc;
407  static const int max_bt = 10; /* max num of regexp backreference allowed, must remain 10 to guarantee a valid backreference index */
408  int size, matchindex; /* size is the size of the backreference sub. */
409  size_t d_len = sizeof(tempdst) - 1;
410  regex_t preg;
411  regmatch_t pmatch[max_bt];
412 
413  tech_return[0] = '\0';
414  dst[0] = '\0';
415 
416  if (len < sizeof(struct naptr)) {
417  ast_log(LOG_WARNING, "NAPTR record length too short\n");
418  return -1;
419  }
420  answer += sizeof(struct naptr);
421  len -= sizeof(struct naptr);
422  if ((res = parse_ie(flags, sizeof(flags) - 1, answer, len)) < 0) {
423  ast_log(LOG_WARNING, "Failed to get flags from NAPTR record\n");
424  return -1;
425  } else {
426  answer += res;
427  len -= res;
428  }
429 
430  if ((res = parse_ie(services, sizeof(services) - 1, answer, len)) < 0) {
431  ast_log(LOG_WARNING, "Failed to get services from NAPTR record\n");
432  return -1;
433  } else {
434  answer += res;
435  len -= res;
436  }
437  if ((res = parse_ie(regexp, sizeof(regexp) - 1, answer, len)) < 0) {
438  ast_log(LOG_WARNING, "Failed to get regexp from NAPTR record\n");
439  return -1;
440  } else {
441  answer += res;
442  len -= res;
443  }
444 
445  if ((res = dn_expand((unsigned char *)oanswer, (unsigned char *)answer + len, (unsigned char *)answer, repl, sizeof(repl) - 1)) < 0) {
446  ast_log(LOG_WARNING, "Failed to expand hostname\n");
447  return -1;
448  }
449 
450  ast_debug(3, "NAPTR input='%s', flags='%s', services='%s', regexp='%s', repl='%s'\n",
451  naptrinput, flags, services, regexp, repl);
452 
453 
454  if (tolower(flags[0]) != 'u') {
455  ast_log(LOG_WARNING, "NAPTR Flag must be 'U' or 'u'.\n");
456  return -1;
457  }
458 
459  p = strstr(services, "e2u+");
460  if (p == NULL)
461  p = strstr(services, "E2U+");
462  if (p){
463  p = p + 4;
464  if (strchr(p, ':')){
465  p = strchr(p, ':') + 1;
466  }
467  ast_copy_string(tech_return, p, sizeof(tech_return));
468  } else {
469 
470  p = strstr(services, "+e2u");
471  if (p == NULL)
472  p = strstr(services, "+E2U");
473  if (p) {
474  *p = 0;
475  p = strchr(services, ':');
476  if (p)
477  *p = 0;
478  ast_copy_string(tech_return, services, sizeof(tech_return));
479  }
480  }
481 
482  regexp_len = strlen(regexp);
483  if (regexp_len < 7) {
484  ast_log(LOG_WARNING, "Regex too short to be meaningful.\n");
485  return -1;
486  }
487 
488  /* this takes the first character of the regexp (which is a delimiter)
489  * and uses that character to find the index of the second delimiter */
490  delim = regexp[0];
491  delim2 = strchr(regexp + 1, delim);
492  if ((delim2 == NULL) || (regexp[regexp_len - 1] != delim)) { /* is the second delimiter found, and is the end of the regexp a delimiter */
493  ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp);
494  return -1;
495  } else if (strchr((delim2 + 1), delim) == NULL) { /* if the second delimiter is found, make sure there is a third instance. this could be the end one instead of the middle */
496  ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp);
497  return -1;
498  }
499  pattern = regexp + 1; /* pattern is the regex without the begining and ending delimiter */
500  *delim2 = 0; /* zero out the middle delimiter */
501  subst = delim2 + 1; /* dst substring is everything after the second delimiter. */
502  regexp[regexp_len - 1] = 0; /* zero out the last delimiter */
503 
504 /*
505  * now do the regex wizardry.
506  */
507 
508  if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) {
509  ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n", regexp);
510  return -1;
511  }
512 
513  if (preg.re_nsub > ARRAY_LEN(pmatch)) {
514  ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n");
515  regfree(&preg);
516  return -1;
517  }
518  /* pmatch is an array containing the substring indexes for the regex backreference sub.
519  * max_bt is the maximum number of backreferences allowed to be stored in pmatch */
520  if ((rc = regexec(&preg, (char *) naptrinput, max_bt, pmatch, 0))) {
521  regerror(rc, &preg, errbuff, sizeof(errbuff));
522  ast_log(LOG_WARNING, "NAPTR Regex match failed. Reason: %s\n", errbuff);
523  regfree(&preg);
524  return -1;
525  }
526  regfree(&preg);
527 
528  d = tempdst;
529  d_len--;
530 
531  /* perform the backreference sub. Search the subst for backreferences,
532  * when a backreference is found, retrieve the backreferences number.
533  * use the backreference number as an index for pmatch to retrieve the
534  * beginning and ending indexes of the substring to insert as the backreference.
535  * if no backreference is found, continue copying the subst into tempdst */
536  while (*subst && (d_len > 0)) {
537  if ((subst[0] == '\\') && isdigit(subst[1])) { /* is this character the beginning of a backreference */
538  matchindex = (int) (subst[1] - '0');
539  if (matchindex >= ARRAY_LEN(pmatch)) {
540  ast_log(LOG_WARNING, "Error during regex substitution. Invalid pmatch index.\n");
541  return -1;
542  }
543  /* pmatch len is 10. we are garanteed a single char 0-9 is a valid index */
544  size = pmatch[matchindex].rm_eo - pmatch[matchindex].rm_so;
545  if (size > d_len) {
546  ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n");
547  return -1;
548  }
549  /* are the pmatch indexes valid for the input length */
550  if ((strlen((char *) naptrinput) >= pmatch[matchindex].rm_eo) && (pmatch[matchindex].rm_so <= pmatch[matchindex].rm_eo)) {
551  memcpy(d, (naptrinput + (int) pmatch[matchindex].rm_so), size); /* copy input substring into backreference marker */
552  d_len -= size;
553  subst += 2; /* skip over backreference characters to next valid character */
554  d += size;
555  } else {
556  ast_log(LOG_WARNING, "Error during regex substitution. Invalid backreference index.\n");
557  return -1;
558  }
559  } else if (isprint(*subst)) {
560  *d++ = *subst++;
561  d_len--;
562  } else {
563  ast_log(LOG_WARNING, "Error during regex substitution.\n");
564  return -1;
565  }
566  }
567  *d = 0;
568  ast_copy_string((char *) dst, tempdst, dstsize);
569  dst[dstsize - 1] = '\0';
570 
571  if (*tech != '\0'){ /* check if it is requested NAPTR */
572  if (!strncasecmp(tech, "ALL", techsize)){
573  return 0; /* return or count any RR */
574  }
575  if (!strncasecmp(tech_return, tech, sizeof(tech_return) < techsize ? sizeof(tech_return): techsize)){
576  ast_copy_string(tech, tech_return, techsize);
577  return 0; /* we got our RR */
578  } else { /* go to the next RR in the DNS answer */
579  return 1;
580  }
581  }
582 
583  /* tech was not specified, return first parsed RR */
584  ast_copy_string(tech, tech_return, techsize);
585 
586  return 0;
587 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char * dst
Definition: enum.h:41
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static unsigned int parse_ie(char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen)
Parse NAPTR record information elements.
Definition: enum.c:370
Definition: enum.h:28
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int private_enum_init ( int  reload)
static

Initialize the ENUM support subsystem.

Definition at line 968 of file enum.c.

References ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, enumlock, ENUMLOOKUP_BLR_CC, ENUMLOOKUP_BLR_EBL, ENUMLOOKUP_BLR_TXT, EVENT_FLAG_SYSTEM, LOG_WARNING, manager_event, and string.

Referenced by ast_enum_init(), and ast_enum_reload().

969 {
970  struct ast_config *cfg;
971  const char *string;
972  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
973 
974  if ((cfg = ast_config_load2("enum.conf", "enum", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
975  return 0;
977  return 0;
978  }
979 
980  /* Destroy existing list */
982  if (cfg) {
983  if ((string = ast_variable_retrieve(cfg, "ienum", "branchlabel"))) {
985  }
986 
987  if ((string = ast_variable_retrieve(cfg, "ienum", "ebl_alg"))) {
988  ebl_alg = ENUMLOOKUP_BLR_CC; /* default */
989 
990  if (!strcasecmp(string, "txt"))
992  else if (!strcasecmp(string, "ebl"))
994  else if (!strcasecmp(string, "cc"))
996  else
997  ast_log(LOG_WARNING, "No valid parameter for ienum/ebl_alg.\n");
998  }
999  ast_config_destroy(cfg);
1000  }
1002  manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: Enum\r\nStatus: Enabled\r\nMessage: ENUM reload Requested\r\n");
1003  return 0;
1004 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static char ienum_branchlabel[32]
Definition: enum.c:85
#define LOG_WARNING
Definition: logger.h:144
static ast_mutex_t enumlock
Definition: enum.c:95
static int ebl_alg
Definition: enum.c:90
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ENUMLOOKUP_BLR_CC
Definition: enum.c:87
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ENUMLOOKUP_BLR_EBL
Definition: enum.c:89
static int reload(void)
Definition: app_amd.c:497
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char string[1]
Definition: utils.c:1722
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
#define ENUMLOOKUP_BLR_TXT
Definition: enum.c:88
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int txt_callback ( void *  context,
unsigned char *  answer,
int  len,
unsigned char *  fullanswer 
)
static

Callback for TXT record lookup, /ol version.

Definition at line 145 of file enum.c.

References ast_copy_string(), ast_log(), context, LOG_WARNING, txt_context::txt, and txt_context::txtlen.

Referenced by blr_txt().

146 {
147  struct txt_context *c = context;
148  unsigned int i;
149 
150  c->txt[0] = 0; /* default to empty */
151  c->txtlen = 0;
152 
153  if (answer == NULL) {
154  return 0;
155  }
156 
157  /* RFC1035:
158  *
159  * <character-string> is a single length octet followed by that number of characters.
160  * TXT-DATA One or more <character-string>s.
161  *
162  * We only take the first string here.
163  */
164 
165  i = *answer++;
166  len -= 1;
167 
168  if (i > len) { /* illegal packet */
169  ast_log(LOG_WARNING, "txt_callback: malformed TXT record.\n");
170  return 0;
171  }
172 
173  if (i >= sizeof(c->txt)) { /* too long? */
174  ast_log(LOG_WARNING, "txt_callback: TXT record too long.\n");
175  i = sizeof(c->txt) - 1;
176  }
177 
178  ast_copy_string(c->txt, (char *)answer, i + 1); /* this handles the \0 termination */
179  c->txtlen = i;
180 
181  return 1;
182 }
char txt[1024]
Definition: enum.c:140
#define LOG_WARNING
Definition: logger.h:144
int txtlen
Definition: enum.c:141
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107

Variable Documentation

int ebl_alg = ENUMLOOKUP_BLR_CC
static

Definition at line 90 of file enum.c.

ast_mutex_t enumlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 95 of file enum.c.

Referenced by ast_get_enum(), blr_ebl(), blr_txt(), and private_enum_init().

char ienum_branchlabel[32] = "i"
static

Definition at line 85 of file enum.c.