Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Functions | Variables
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/module.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"
Include dependency graph for enum.c:

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

static void __reg_module (void)
 
static void __unreg_module (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...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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 char * format_numeric_domain (const char *number, const char *suffix)
 
static int load_module (void)
 
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 reload_module (void)
 
static int txt_callback (void *context, unsigned char *answer, int len, unsigned char *fullanswer)
 Callback for TXT record lookup, /ol version. More...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "ENUM Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int ebl_alg = ENUMLOOKUP_BLR_CC
 
static ast_mutex_t enumlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
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
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

◆ ENUMLOOKUP_BLR_CC

#define ENUMLOOKUP_BLR_CC   0

Definition at line 93 of file enum.c.

◆ ENUMLOOKUP_BLR_EBL

#define ENUMLOOKUP_BLR_EBL   2

Definition at line 95 of file enum.c.

◆ ENUMLOOKUP_BLR_TXT

#define ENUMLOOKUP_BLR_TXT   1

Definition at line 94 of file enum.c.

◆ ENUMLOOKUP_OPTIONS_COUNT

#define ENUMLOOKUP_OPTIONS_COUNT   1

Definition at line 607 of file enum.c.

◆ ENUMLOOKUP_OPTIONS_DIRECT

#define ENUMLOOKUP_OPTIONS_DIRECT   8

Definition at line 613 of file enum.c.

◆ ENUMLOOKUP_OPTIONS_IENUM

#define ENUMLOOKUP_OPTIONS_IENUM   4

Definition at line 611 of file enum.c.

◆ ENUMLOOKUP_OPTIONS_ISN

#define ENUMLOOKUP_OPTIONS_ISN   2

Definition at line 609 of file enum.c.

◆ T_EBL

#define T_EBL   65300

Definition at line 99 of file enum.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1089 of file enum.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1089 of file enum.c.

◆ ast_get_enum()

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

650{
651 struct enum_context *context;
652 char tmp[512];
653 char domain[256];
654 char left[128];
655 char middle[128];
656 char naptrinput[128];
657 char apex[128] = "";
658 int ret = -1;
659 /* for ISN rewrite */
660 char *p1 = NULL;
661 char *p2 = NULL;
662 char *p3 = NULL;
663 int k = 0;
664 int i = 0;
665 int z = 0;
666 int spaceleft = 0;
667 struct timeval time_start, time_end;
668
669 if (ast_strlen_zero(suffix)) {
670 ast_log(LOG_WARNING, "ast_get_enum need a suffix parameter now.\n");
671 return -1;
672 }
673
674 ast_debug(2, "num='%s', tech='%s', suffix='%s', options='%s', record=%u\n", number, tech, suffix, options, record);
675
676/*
677 We don't need that any more, that "n" preceding the number has been replaced by a flag
678 in the options paramter.
679 ast_copy_string(naptrinput, number, sizeof(naptrinput));
680*/
681/*
682 * The "number" parameter includes a leading '+' if it's a full E.164 number (and not ISN)
683 * We need to preserve that as the regex inside NAPTRs expect the +.
684 *
685 * But for the domain generation, the '+' is a nuisance, so we get rid of it.
686*/
687 ast_copy_string(naptrinput, number[0] == 'n' ? number + 1 : number, sizeof(naptrinput));
688 if (number[0] == '+') {
689 number++;
690 }
691
692 if (!(context = ast_calloc(1, sizeof(*context)))) {
693 return -1;
694 }
695
696 if ((p3 = strchr(naptrinput, '*'))) {
697 *p3='\0';
698 }
699
700 context->naptrinput = naptrinput; /* The number */
701 context->dst = dst; /* Return string */
702 context->dstlen = dstlen;
703 context->tech = tech;
704 context->techlen = techlen;
705 context->options = 0;
706 context->position = record > 0 ? record : 1;
707 context->count = 0;
708 context->naptr_rrs = NULL;
709 context->naptr_rrs_count = 0;
710
711 /*
712 * Process options:
713 *
714 * c Return count, not URI
715 * i Use infrastructure ENUM
716 * s Do ISN transformation
717 * d Direct DNS query: no reversing.
718 *
719 */
720 if (options != NULL) {
721 if (strchr(options,'s')) {
723 } else if (strchr(options,'i')) {
725 } else if (strchr(options,'d')) {
727 }
728 if (strchr(options,'c')) {
730 }
731 if (strchr(number,'*')) {
733 }
734 }
735 ast_debug(2, "ENUM options(%s): pos=%d, options='%d'\n", options, context->position, context->options);
736 ast_debug(1, "n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n",
737 number, tech, suffix, context->options, context->position);
738
739 /*
740 * This code does more than simple RFC3261 ENUM. All these rewriting
741 * schemes have in common that they build the FQDN for the NAPTR lookup
742 * by concatenating
743 * - a number which needs be flipped and "."-seperated (left)
744 * - some fixed string (middle)
745 * - an Apex. (apex)
746 *
747 * The RFC3261 ENUM is: left=full number, middle="", apex=from args.
748 * ISN: number = "middle*left", apex=from args
749 * I-ENUM: EBL parameters build the split, can change apex
750 * Direct: left="", middle=argument, apex=from args
751 *
752 */
753
754 /* default: the whole number will be flipped, no middle domain component */
755 ast_copy_string(left, number, sizeof(left));
756 middle[0] = '\0';
757 /*
758 * I-ENUM can change the apex, thus we copy it
759 */
760 ast_copy_string(apex, suffix, sizeof(apex));
761 /* ISN rewrite */
762 if ((context->options & ENUMLOOKUP_OPTIONS_ISN) && (p1 = strchr(number, '*'))) {
763 *p1++ = '\0';
764 ast_copy_string(left, number, sizeof(left));
765 ast_copy_string(middle, p1, sizeof(middle) - 1);
766 strcat(middle, ".");
767 ast_debug(2, "ISN ENUM: left=%s, middle='%s'\n", left, middle);
768 /* Direct DNS lookup rewrite */
769 } else if (context->options & ENUMLOOKUP_OPTIONS_DIRECT) {
770 left[0] = 0; /* nothing to flip around */
771 ast_copy_string(middle, number, sizeof(middle) - 1);
772 strcat(middle, ".");
773 ast_debug(2, "DIRECT ENUM: middle='%s'\n", middle);
774 /* Infrastructure ENUM rewrite */
775 } else if (context->options & ENUMLOOKUP_OPTIONS_IENUM) {
776 int sdl = 0;
777 char cc[8];
778 char sep[256], n_apex[256];
779 int cc_len = cclen(number);
780 sdl = cc_len;
782 ast_copy_string(sep, ienum_branchlabel, sizeof(sep)); /* default */
784
785 switch (ebl_alg) {
787 ast_copy_string(cc, number, cc_len); /* cclen() never returns more than 3 */
788 sdl = blr_ebl(cc, suffix, sep, sizeof(sep) - 1, n_apex, sizeof(n_apex) - 1);
789
790 if (sdl >= 0) {
791 ast_copy_string(apex, n_apex, sizeof(apex));
792 ast_debug(2, "EBL ENUM: sep=%s, apex='%s'\n", sep, n_apex);
793 } else {
794 sdl = cc_len;
795 }
796 break;
798 ast_copy_string(cc, number, cc_len); /* cclen() never returns more than 3 */
799 sdl = blr_txt(cc, suffix);
800
801 if (sdl < 0) {
802 sdl = cc_len;
803 }
804 break;
805
806 case ENUMLOOKUP_BLR_CC: /* BLR is at the country-code level */
807 default:
808 sdl = cc_len;
809 break;
810 }
811
812 if (sdl > strlen(number)) { /* Number too short for this sdl? */
813 ast_log(LOG_WARNING, "I-ENUM: subdomain location %d behind number %s\n", sdl, number);
815 return 0;
816 }
817 ast_copy_string(left, number + sdl, sizeof(left));
818
820 ast_copy_string(middle, sep, sizeof(middle) - 1);
821 strcat(middle, ".");
823
824 /* check the space we need for middle */
825 if ((sdl * 2 + strlen(middle) + 2) > sizeof(middle)) {
826 ast_log(LOG_WARNING, "ast_get_enum: not enough space for I-ENUM rewrite.\n");
828 return -1;
829 }
830
831 p1 = middle + strlen(middle);
832 for (p2 = (char *) number + sdl - 1; p2 >= number; p2--) {
833 if (isdigit(*p2)) {
834 *p1++ = *p2;
835 *p1++ = '.';
836 }
837 }
838 *p1 = '\0';
839
840 ast_debug(2, "I-ENUM: cclen=%d, left=%s, middle='%s', apex='%s'\n", cc_len, left, middle, apex);
841 }
842
843 if (strlen(left) * 2 + 2 > sizeof(domain)) {
844 ast_log(LOG_WARNING, "string to long in ast_get_enum\n");
846 return -1;
847 }
848
849 /* flip left into domain */
850 p1 = domain;
851 for (p2 = left + strlen(left); p2 >= left; p2--) {
852 if (isdigit(*p2)) {
853 *p1++ = *p2;
854 *p1++ = '.';
855 }
856 }
857 *p1 = '\0';
858
859 if (chan && ast_autoservice_start(chan) < 0) {
861 return -1;
862 }
863
864 spaceleft = sizeof(tmp) - 2;
865 ast_copy_string(tmp, domain, spaceleft);
866 spaceleft -= strlen(domain);
867
868 if (*middle) {
869 strncat(tmp, middle, spaceleft);
870 spaceleft -= strlen(middle);
871 }
872
873 strncat(tmp,apex,spaceleft);
874 time_start = ast_tvnow();
875 ret = ast_search_dns(context, tmp, C_IN, T_NAPTR, enum_callback);
876 time_end = ast_tvnow();
877
878 ast_debug(2, "profiling: %s, %s, %" PRIi64 " ms\n",
879 (ret == 0) ? "OK" : "FAIL", tmp, ast_tvdiff_ms(time_end, time_start));
880
881 if (ret < 0) {
882 ast_debug(1, "No such number found: %s (%s)\n", tmp, strerror(errno));
883 context->naptr_rrs_count = -1;
884 strcpy(dst, "0");
885 ret = 0;
886 }
887
888 if (context->naptr_rrs_count >= context->position && ! (context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
889 /* sort array by NAPTR order/preference */
890 for (k = 0; k < context->naptr_rrs_count; k++) {
891 for (i = 0; i < context->naptr_rrs_count; i++) {
892 /* use order first and then preference to compare */
893 if ((ntohs(context->naptr_rrs[k].naptr.order) < ntohs(context->naptr_rrs[i].naptr.order)
894 && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
895 || (ntohs(context->naptr_rrs[k].naptr.order) > ntohs(context->naptr_rrs[i].naptr.order)
896 && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)) {
897 z = context->naptr_rrs[k].sort_pos;
898 context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
899 context->naptr_rrs[i].sort_pos = z;
900 continue;
901 }
902 if (ntohs(context->naptr_rrs[k].naptr.order) == ntohs(context->naptr_rrs[i].naptr.order)) {
903 if ((ntohs(context->naptr_rrs[k].naptr.pref) < ntohs(context->naptr_rrs[i].naptr.pref)
904 && context->naptr_rrs[k].sort_pos > context->naptr_rrs[i].sort_pos)
905 || (ntohs(context->naptr_rrs[k].naptr.pref) > ntohs(context->naptr_rrs[i].naptr.pref)
906 && context->naptr_rrs[k].sort_pos < context->naptr_rrs[i].sort_pos)) {
907 z = context->naptr_rrs[k].sort_pos;
908 context->naptr_rrs[k].sort_pos = context->naptr_rrs[i].sort_pos;
909 context->naptr_rrs[i].sort_pos = z;
910 }
911 }
912 }
913 }
914 for (k = 0; k < context->naptr_rrs_count; k++) {
915 if (context->naptr_rrs[k].sort_pos == context->position - 1) {
916 ast_copy_string(context->dst, context->naptr_rrs[k].result, dstlen);
917 ast_copy_string(context->tech, context->naptr_rrs[k].tech, techlen);
918 break;
919 }
920 }
921 } else if (!(context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
922 context->dst[0] = 0;
923 } else if ((context->options & ENUMLOOKUP_OPTIONS_COUNT)) {
924 snprintf(context->dst, context->dstlen, "%d", context->naptr_rrs_count + context->count);
925 }
926
927 if (chan) {
928 ret |= ast_autoservice_stop(chan);
929 }
930
931 if (!argcontext) {
932 for (k = 0; k < context->naptr_rrs_count; k++) {
933 ast_free(context->naptr_rrs[k].result);
934 ast_free(context->naptr_rrs[k].tech);
935 }
936 ast_free(context->naptr_rrs);
938 } else {
939 *argcontext = context;
940 }
941
942 return ret;
943}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
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:491
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:330
#define ENUMLOOKUP_BLR_TXT
Definition: enum.c:94
static char ienum_branchlabel[32]
Definition: enum.c:91
#define ENUMLOOKUP_BLR_CC
Definition: enum.c:93
#define ENUMLOOKUP_OPTIONS_COUNT
Definition: enum.c:607
#define ENUMLOOKUP_BLR_EBL
Definition: enum.c:95
static int enum_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Callback from ENUM lookup function.
Definition: enum.c:616
static int cclen(const char *number)
Determine the length of a country code when given an E.164 string.
Definition: enum.c:116
static ast_mutex_t enumlock
Definition: enum.c:101
#define ENUMLOOKUP_OPTIONS_ISN
Definition: enum.c:609
static int blr_txt(const char *cc, const char *suffix)
Determine the branch location record as stored in a TXT record.
Definition: enum.c:201
#define ENUMLOOKUP_OPTIONS_IENUM
Definition: enum.c:611
#define ENUMLOOKUP_OPTIONS_DIRECT
Definition: enum.c:613
static int ebl_alg
Definition: enum.c:96
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
int errno
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char * naptrinput
Definition: enum.h:49
Number structure.
Definition: app_followme.c:154
static struct test_options options
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

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(), voicemailpwcheck::context, ebl_alg, 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, ienum_branchlabel, LOG_WARNING, enum_context::naptrinput, NULL, options, and tmp().

Referenced by enum_query_read(), and function_enum().

◆ ast_get_txt()

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

996{
997 struct txt_context context;
998 char *domain;
999 int ret;
1000 int autoservice = 0;
1001
1002 ast_debug(4, "ast_get_txt: Number = '%s', suffix = '%s'\n", number, suffix);
1003
1004 domain = format_numeric_domain(number, suffix);
1005 if (!domain) {
1006 return -1;
1007 }
1008
1009 if (chan) {
1010 /* DNS might take a while, so service the channel while we're blocked */
1011 autoservice = !ast_autoservice_start(chan);
1012 }
1013
1014 ret = ast_search_dns(&context, domain, C_IN, T_TXT, txt_callback);
1015 if (ret > 0) {
1017 } else {
1018 ast_debug(2, "No such number found in ENUM: %s (%s)\n", domain, strerror(errno));
1019 }
1020
1021 if (autoservice) {
1023 }
1024
1025 ast_free(domain);
1026 return 0;
1027}
static int txt_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Callback for TXT record lookup, /ol version.
Definition: enum.c:151
static char * format_numeric_domain(const char *number, const char *suffix)
Definition: enum.c:955
int txtlen
Definition: enum.c:147
char txt[1024]
Definition: enum.c:146

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_debug, ast_free, ast_search_dns(), voicemailpwcheck::context, errno, format_numeric_domain(), txt_context::txt, txt_callback(), and txt_context::txtlen.

Referenced by function_txtcidname().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1089 of file enum.c.

◆ blr_ebl()

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

331{
332 struct ebl_context context;
333 char domain[128] = "";
334 char *p1,*p2;
335 int ret;
336
338
339 ast_verb(4, "blr_ebl() cc='%s', suffix='%s', c_bl='%s'\n", cc, suffix, ienum_branchlabel);
340
341 if (sizeof(domain) < (strlen(cc) * 2 + strlen(ienum_branchlabel) + strlen(suffix) + 2)) {
343 ast_log(LOG_WARNING, "ERROR: string sizing in blr_EBL.\n");
344 return -1;
345 }
346
347 p1 = domain + snprintf(domain, sizeof(domain), "%s.", ienum_branchlabel);
349
350 for (p2 = (char *) cc + strlen(cc) - 1; p2 >= cc; p2--) {
351 if (isdigit(*p2)) {
352 *p1++ = *p2;
353 *p1++ = '.';
354 }
355 }
356 strcat(p1, suffix);
357
358 ast_verb(4, "blr_ebl() FQDN for EBL record: %s, cc was %s\n", domain, cc);
359
360 ret = ast_search_dns(&context, domain, C_IN, T_EBL, ebl_callback);
361 if (ret > 0) {
362 ret = context.pos;
363
364 if ((ret >= 0) && (ret < 20)) {
365 ast_verb(3, "blr_txt() BLR EBL record for %s is %d/%s/%s)\n", cc, ret, context.separator, context.apex);
368 return ret;
369 }
370 }
371 ast_verb(3, "blr_txt() BLR EBL record for %s not found (apex: %s)\n", cc, suffix);
372 return -1;
373}
#define T_EBL
Definition: enum.c:99
static int ebl_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Callback for EBL record lookup.
Definition: enum.c:256
#define ast_verb(level,...)
char apex[256]
Definition: enum.c:251
char separator[256]
Definition: enum.c:249
int apex_len
Definition: enum.c:252
int sep_len
Definition: enum.c:250

References ebl_context::apex, ebl_context::apex_len, ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_search_dns(), ast_verb, voicemailpwcheck::context, ebl_callback(), enumlock, ienum_branchlabel, LOG_WARNING, ebl_context::sep_len, ebl_context::separator, and T_EBL.

Referenced by ast_get_enum().

◆ blr_txt()

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

202{
203 struct txt_context context;
204 char domain[128] = "";
205 char *p1, *p2;
206 int ret;
207
209
210 ast_verb(4, "blr_txt() cc='%s', suffix='%s', c_bl='%s'\n", cc, suffix, ienum_branchlabel);
211
212 if (sizeof(domain) < (strlen(cc) * 2 + strlen(ienum_branchlabel) + strlen(suffix) + 2)) {
214 ast_log(LOG_WARNING, "ERROR: string sizing in blr_txt.\n");
215 return -1;
216 }
217
218 p1 = domain + snprintf(domain, sizeof(domain), "%s.", ienum_branchlabel);
220
221 for (p2 = (char *) cc + strlen(cc) - 1; p2 >= cc; p2--) {
222 if (isdigit(*p2)) {
223 *p1++ = *p2;
224 *p1++ = '.';
225 }
226 }
227 strcat(p1, suffix);
228
229 ast_verb(4, "blr_txt() FQDN for TXT record: %s, cc was %s\n", domain, cc);
230
231 ret = ast_search_dns(&context, domain, C_IN, T_TXT, txt_callback);
232
233 if (ret > 0) {
234 ret = atoi(context.txt);
235
236 if ((ret >= 0) && (ret < 20)) {
237 ast_verb(3, "blr_txt() BLR TXT record for %s is %d (apex: %s)\n", cc, ret, suffix);
238 return ret;
239 }
240 }
241
242 ast_verb(3, "blr_txt() BLR TXT record for %s not found (apex: %s)\n", cc, suffix);
243
244 return -1;
245}

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_search_dns(), ast_verb, voicemailpwcheck::context, enumlock, ienum_branchlabel, LOG_WARNING, and txt_callback().

Referenced by ast_get_enum().

◆ cclen()

static int cclen ( const char *  number)
static

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

Definition at line 116 of file enum.c.

117{
118 int cc;
119 char digits[3] = "";
120
121 if (!number || (strlen(number) < 3)) {
122 return 0;
123 }
124
125 strncpy(digits, number, 2);
126
127 if (!sscanf(digits, "%30d", &cc)) {
128 return 0;
129 }
130
131 if (cc / 10 == 1 || cc / 10 == 7)
132 return 1;
133
134 if (cc == 20 || cc == 27 || (cc >= 30 && cc <= 34) || cc == 36 ||
135 cc == 39 || cc == 40 || cc == 41 || (cc >= 40 && cc <= 41) ||
136 (cc >= 43 && cc <= 49) || (cc >= 51 && cc <= 58) ||
137 (cc >= 60 && cc <= 66) || cc == 81 || cc == 82 || cc == 84 ||
138 cc == 86 || (cc >= 90 && cc <= 95) || cc == 98) {
139 return 2;
140 }
141
142 return 3;
143}

Referenced by ast_get_enum().

◆ ebl_callback()

static int ebl_callback ( void *  context,
unsigned char *  answer,
int  len,
unsigned char *  fullanswer 
)
static

Callback for EBL record lookup.

Definition at line 256 of file enum.c.

257{
258 struct ebl_context *c = context;
259 int i;
260
261 c->pos = 0; /* default to empty */
262 c->separator[0] = 0;
263 c->sep_len = 0;
264 c->apex[0] = 0;
265 c->apex_len = 0;
266
267 if (answer == NULL) {
268 return 0;
269 }
270
271 /* draft-lendl-enum-branch-location-record-00
272 *
273 * 0 1 2 3 4 5 6 7
274 * +--+--+--+--+--+--+--+--+
275 * | POSITION |
276 * +--+--+--+--+--+--+--+--+
277 * / SEPARATOR /
278 * +--+--+--+--+--+--+--+--+
279 * / APEX /
280 * +--+--+--+--+--+--+--+--+
281 *
282 * where POSITION is a single byte, SEPARATOR is a <character-string>
283 * and APEX is a <domain-name>.
284 *
285 */
286
287 c->pos = *answer++;
288 len -= 1;
289
290 if ((c->pos > 15) || len < 2) { /* illegal packet */
291 ast_log(LOG_WARNING, "ebl_callback: malformed EBL record.\n");
292 return 0;
293 }
294
295 i = *answer++;
296 len -= 1;
297 if (i > len) { /* illegal packet */
298 ast_log(LOG_WARNING, "ebl_callback: malformed EBL record.\n");
299 return 0;
300 }
301
302 ast_copy_string(c->separator, (char *)answer, i + 1);
303 c->sep_len = i;
304
305 answer += i;
306 len -= i;
307
308 if ((i = dn_expand((unsigned char *)fullanswer, (unsigned char *)answer + len,
309 (unsigned char *)answer, c->apex, sizeof(c->apex) - 1)) < 0) {
310 ast_log(LOG_WARNING, "Failed to expand hostname\n");
311 return 0;
312 }
313 c->apex[i] = 0;
314 c->apex_len = i;
315
316 return 1;
317}
static int answer(void *data)
Definition: chan_pjsip.c:683
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static struct test_val c

References answer(), ast_copy_string(), ast_log, c, voicemailpwcheck::context, len(), LOG_WARNING, and NULL.

Referenced by blr_ebl().

◆ enum_callback()

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

Callback from ENUM lookup function.

Definition at line 616 of file enum.c.

617{
618 struct enum_context *c = context;
619 void *p = NULL;
620 int res;
621
622 res = parse_naptr((unsigned char *)c->dst, c->dstlen, c->tech, c->techlen, answer, len, (unsigned char *)c->naptrinput);
623
624 if (res < 0) {
625 ast_log(LOG_WARNING, "Failed to parse naptr\n");
626 return -1;
627 } else if ((res == 0) && !ast_strlen_zero(c->dst)) { /* ok, we got needed NAPTR */
628 if (c->options & ENUMLOOKUP_OPTIONS_COUNT) { /* counting RRs */
629 c->count++;
630 snprintf(c->dst, c->dstlen, "%d", c->count);
631 } else {
632 if ((p = ast_realloc(c->naptr_rrs, sizeof(*c->naptr_rrs) * (c->naptr_rrs_count + 1)))) {
633 c->naptr_rrs = p;
634 memcpy(&c->naptr_rrs[c->naptr_rrs_count].naptr, answer, sizeof(c->naptr_rrs->naptr));
635 c->naptr_rrs[c->naptr_rrs_count].result = ast_strdup(c->dst);
636 c->naptr_rrs[c->naptr_rrs_count].tech = ast_strdup(c->tech);
637 c->naptr_rrs[c->naptr_rrs_count].sort_pos = c->naptr_rrs_count;
638 c->naptr_rrs_count++;
639 }
640 c->dst[0] = 0;
641 }
642 return 0;
643 }
644
645 return 0;
646}
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
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:397

References answer(), ast_log, ast_realloc, ast_strdup, ast_strlen_zero(), c, voicemailpwcheck::context, ENUMLOOKUP_OPTIONS_COUNT, len(), LOG_WARNING, NULL, and parse_naptr().

Referenced by ast_get_enum().

◆ format_numeric_domain()

static char * format_numeric_domain ( const char *  number,
const char *  suffix 
)
static

Definition at line 955 of file enum.c.

956{
957 char *buffer, *dst;
958 size_t suffix_length;
959 size_t number_length = strlen(number);
960 const char *src = number + number_length - 1;
961
962 if (!suffix) {
963 suffix = "e164.arpa";
964 }
965
966 suffix_length = strlen(suffix);
967
968 dst = buffer = ast_malloc(
969 (number_length * 2) /* We need 2 bytes per input digit */
970 + suffix_length /* ... plus however long the suffix is */
971 + 1 /* ... plus room for the '.' separator */
972 + 1 /* ... and room for the \0 byte at the end */);
973
974 if (buffer) {
975 while (src >= number) {
976 if (isdigit(*src)) {
977 *dst++ = *src;
978 *dst++ = '.';
979 }
980 src--;
981 }
982
983 /* The length arguments below make sure that the \0 byte is copied into
984 the final string */
985 if (*suffix == '.') {
986 memcpy(dst, &suffix[1], suffix_length);
987 } else {
988 memcpy(dst, suffix, suffix_length + 1);
989 }
990 }
991
992 return buffer;
993}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191

References ast_malloc.

Referenced by ast_get_txt().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1067 of file enum.c.

1068{
1070}
static int private_enum_init(int reload)
Initialize the ENUM support subsystem.
Definition: enum.c:1030
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, and private_enum_init().

◆ parse_ie()

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

377{
378 unsigned int len, olen;
379
380 len = olen = (unsigned int) src[0];
381 src++;
382 srclen--;
383
384 if (len > srclen) {
385 ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %u characters, got %u\n", len, srclen);
386 return -1;
387 }
388
389 if (len > maxdatalen)
390 len = maxdatalen;
391 memcpy(data, src, len);
392
393 return olen + 1;
394}

References ast_log, len(), and LOG_WARNING.

Referenced by parse_naptr().

◆ parse_naptr()

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

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

References answer(), ARRAY_LEN, ast_copy_string(), ast_debug, ast_log, d, len(), LOG_WARNING, NULL, and parse_ie().

Referenced by enum_callback().

◆ private_enum_init()

static int private_enum_init ( int  reload)
static

Initialize the ENUM support subsystem.

Definition at line 1030 of file enum.c.

1031{
1032 struct ast_config *cfg;
1033 const char *string;
1034 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1035
1036 if ((cfg = ast_config_load2("enum.conf", "enum", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
1037 return 0;
1039 return 0;
1040 }
1041
1042 /* Destroy existing list */
1044 if (cfg) {
1045 if ((string = ast_variable_retrieve(cfg, "ienum", "branchlabel"))) {
1047 }
1048
1049 if ((string = ast_variable_retrieve(cfg, "ienum", "ebl_alg"))) {
1050 ebl_alg = ENUMLOOKUP_BLR_CC; /* default */
1051
1052 if (!strcasecmp(string, "txt"))
1054 else if (!strcasecmp(string, "ebl"))
1056 else if (!strcasecmp(string, "cc"))
1058 else
1059 ast_log(LOG_WARNING, "No valid parameter for ienum/ebl_alg.\n");
1060 }
1061 ast_config_destroy(cfg);
1062 }
1064 return 0;
1065}
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
@ CONFIG_FLAG_FILEUNCHANGED
const char * string
Definition: presencestate.c:71
static int reload(void)
Structure used to handle boolean flags.
Definition: utils.h:199

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, ebl_alg, enumlock, ENUMLOOKUP_BLR_CC, ENUMLOOKUP_BLR_EBL, ENUMLOOKUP_BLR_TXT, ienum_branchlabel, LOG_WARNING, reload(), and string.

Referenced by load_module(), and reload_module().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1077 of file enum.c.

1078{
1079 return private_enum_init(1);
1080}

References private_enum_init().

◆ txt_callback()

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

152{
153 struct txt_context *c = context;
154 unsigned int i;
155
156 c->txt[0] = 0; /* default to empty */
157 c->txtlen = 0;
158
159 if (answer == NULL) {
160 return 0;
161 }
162
163 /* RFC1035:
164 *
165 * <character-string> is a single length octet followed by that number of characters.
166 * TXT-DATA One or more <character-string>s.
167 *
168 * We only take the first string here.
169 */
170
171 i = *answer++;
172 len -= 1;
173
174 if (i > len) { /* illegal packet */
175 ast_log(LOG_WARNING, "txt_callback: malformed TXT record.\n");
176 return 0;
177 }
178
179 if (i >= sizeof(c->txt)) { /* too long? */
180 ast_log(LOG_WARNING, "txt_callback: TXT record too long.\n");
181 i = sizeof(c->txt) - 1;
182 }
183
184 ast_copy_string(c->txt, (char *)answer, i + 1); /* this handles the \0 termination */
185 c->txtlen = i;
186
187 return 1;
188}

References answer(), ast_copy_string(), ast_log, c, voicemailpwcheck::context, len(), LOG_WARNING, and NULL.

Referenced by ast_get_txt(), and blr_txt().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1072 of file enum.c.

1073{
1074 return 0;
1075}

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "ENUM Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 1089 of file enum.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1089 of file enum.c.

◆ ebl_alg

int ebl_alg = ENUMLOOKUP_BLR_CC
static

Definition at line 96 of file enum.c.

Referenced by ast_get_enum(), and private_enum_init().

◆ enumlock

ast_mutex_t enumlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 101 of file enum.c.

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

◆ ienum_branchlabel

char ienum_branchlabel[32] = "i"
static

Definition at line 91 of file enum.c.

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