![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
sip3_domain.c
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 1999 - 2007, Digium, Inc. 00005 * and Edvina AB, Sollentuna, Sweden (chan_sip3 changes/additions) 00006 * 00007 * Mark Spencer <markster@digium.com> 00008 * 00009 * See http://www.asterisk.org for more information about 00010 * the Asterisk project. Please do not directly contact 00011 * any of the maintainers of this project for assistance; 00012 * the project provides a web site, mailing lists and IRC 00013 * channels for your use. 00014 * 00015 * This program is free software, distributed under the terms of 00016 * the GNU General Public License Version 2. See the LICENSE file 00017 * at the top of the source tree. 00018 */ 00019 00020 /*! 00021 * \file 00022 * \brief Various SIP domains function 00023 * Version 3 of chan_sip 00024 * 00025 * \author Mark Spencer <markster@digium.com> 00026 * \author Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes) 00027 * 00028 * See Also: 00029 * \arg \ref AstCREDITS 00030 * 00031 */ 00032 00033 #include "asterisk.h" 00034 00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 53128 $") 00036 00037 #include <stdio.h> 00038 #include <ctype.h> 00039 #include <string.h> 00040 #include <unistd.h> 00041 #include <sys/socket.h> 00042 #include <sys/ioctl.h> 00043 #include <net/if.h> 00044 #include <errno.h> 00045 #include <stdlib.h> 00046 #include <fcntl.h> 00047 #include <netdb.h> 00048 #include <signal.h> 00049 #include <sys/signal.h> 00050 #include <netinet/in.h> 00051 #include <netinet/in_systm.h> 00052 #include <arpa/inet.h> 00053 #include <netinet/ip.h> 00054 #include <regex.h> 00055 00056 #include "asterisk/lock.h" 00057 #include "asterisk/channel.h" 00058 #include "asterisk/config.h" 00059 #include "asterisk/logger.h" 00060 #include "asterisk/module.h" 00061 #include "asterisk/pbx.h" 00062 #include "asterisk/options.h" 00063 #include "asterisk/sched.h" 00064 #include "asterisk/io.h" 00065 #include "asterisk/rtp.h" 00066 #include "asterisk/udptl.h" 00067 #include "asterisk/acl.h" 00068 #include "asterisk/manager.h" 00069 #include "asterisk/callerid.h" 00070 #include "asterisk/cli.h" 00071 #include "asterisk/app.h" 00072 #include "asterisk/musiconhold.h" 00073 #include "asterisk/dsp.h" 00074 #include "asterisk/features.h" 00075 #include "asterisk/srv.h" 00076 #include "asterisk/astdb.h" 00077 #include "asterisk/causes.h" 00078 #include "asterisk/utils.h" 00079 #include "asterisk/file.h" 00080 #include "asterisk/astobj.h" 00081 #include "asterisk/dnsmgr.h" 00082 #include "asterisk/devicestate.h" 00083 #include "asterisk/linkedlists.h" 00084 #include "asterisk/stringfields.h" 00085 #include "asterisk/monitor.h" 00086 #include "asterisk/localtime.h" 00087 #include "asterisk/abstract_jb.h" 00088 #include "asterisk/compiler.h" 00089 #include "sip3.h" 00090 #include "sip3funcs.h" 00091 00092 static AST_LIST_HEAD_STATIC(domain_list, domain); /*!< The SIP domain list */ 00093 00094 /*! \brief Add SIP domain to list of domains we are responsible for */ 00095 int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context) 00096 { 00097 struct domain *d; 00098 00099 if (ast_strlen_zero(domain)) { 00100 ast_log(LOG_WARNING, "Zero length domain.\n"); 00101 return 1; 00102 } 00103 00104 if (!(d = ast_calloc(1, sizeof(*d)))) 00105 return 0; 00106 00107 ast_copy_string(d->domain, domain, sizeof(d->domain)); 00108 00109 if (!ast_strlen_zero(context)) 00110 ast_copy_string(d->context, context, sizeof(d->context)); 00111 00112 d->mode = mode; 00113 00114 AST_LIST_LOCK(&domain_list); 00115 AST_LIST_INSERT_TAIL(&domain_list, d, list); 00116 AST_LIST_UNLOCK(&domain_list); 00117 00118 if (option_debug > 2) 00119 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 00120 00121 return 1; 00122 } 00123 00124 /*! \brief return TRUE if any domains are configured for this server */ 00125 int domains_configured(void) 00126 { 00127 return (!AST_LIST_EMPTY(&domain_list)); 00128 } 00129 00130 00131 /*! \brief check_sip_domain: Check if domain part of uri is local to our server */ 00132 int check_sip_domain(const char *domain, char *context, size_t len) 00133 { 00134 struct domain *d; 00135 int result = 0; 00136 00137 AST_LIST_LOCK(&domain_list); 00138 AST_LIST_TRAVERSE(&domain_list, d, list) { 00139 if (strcasecmp(d->domain, domain)) 00140 continue; 00141 00142 if (len && !ast_strlen_zero(d->context)) 00143 ast_copy_string(context, d->context, len); 00144 00145 result = 1; 00146 break; 00147 } 00148 AST_LIST_UNLOCK(&domain_list); 00149 00150 return result; 00151 } 00152 00153 /*! \brief Clear our domain list (at reload) */ 00154 void clear_sip_domains(void) 00155 { 00156 struct domain *d; 00157 00158 AST_LIST_LOCK(&domain_list); 00159 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 00160 free(d); 00161 AST_LIST_UNLOCK(&domain_list); 00162 } 00163 00164 00165 /*! \brief Dial plan function to check if domain is local */ 00166 int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 00167 { 00168 if (ast_strlen_zero(data)) { 00169 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 00170 return -1; 00171 } 00172 if (check_sip_domain(data, NULL, 0)) 00173 ast_copy_string(buf, data, len); 00174 else 00175 buf[0] = '\0'; 00176 return 0; 00177 } 00178 00179 struct ast_custom_function checksipdomain_function = { 00180 .name = "CHECKSIPDOMAIN", 00181 .synopsis = "Checks if domain is a local domain", 00182 .syntax = "CHECKSIPDOMAIN(<domain|IP>)", 00183 .read = func_check_sipdomain, 00184 .desc = "This function checks if the domain in the argument is configured\n" 00185 "as a local SIP domain that this Asterisk server is configured to handle.\n" 00186 "Returns the domain name if it is locally handled, otherwise an empty string.\n" 00187 "Check the domain= configuration in sip.conf\n", 00188 }; 00189 00190 /*! \brief Print domain mode to cli */ 00191 const char *domain_mode_to_text(const enum domain_mode mode) 00192 { 00193 switch (mode) { 00194 case SIP_DOMAIN_AUTO: 00195 return "[Automatic]"; 00196 case SIP_DOMAIN_CONFIG: 00197 return "[Configured]"; 00198 } 00199 00200 return ""; 00201 } 00202 00203 /*! \brief CLI command to list local domains */ 00204 int sip_show_domains(int fd, int argc, char *argv[]) 00205 { 00206 struct domain *d; 00207 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 00208 00209 if (domains_configured()) { 00210 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 00211 return RESULT_SUCCESS; 00212 } else { 00213 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 00214 AST_LIST_LOCK(&domain_list); 00215 AST_LIST_TRAVERSE(&domain_list, d, list) 00216 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 00217 domain_mode_to_text(d->mode)); 00218 AST_LIST_UNLOCK(&domain_list); 00219 ast_cli(fd, "\n"); 00220 return RESULT_SUCCESS; 00221 } 00222 } 00223 #undef FORMAT