#include "asterisk.h"
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include "asterisk/dahdi_compat.h"
#include <sys/capability.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
Go to the source code of this file.
Defines | |
#define | PPP_EXEC "/usr/sbin/pppd" |
#define | PPP_MAX_ARGS 32 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | exec (struct ast_channel *chan, void *data) |
static int | exec_warn (struct ast_channel *chan, void *data) |
static int | load_module (void) |
static void | run_ras (struct ast_channel *chan, char *args) |
static pid_t | spawn_ras (struct ast_channel *chan, char *args) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "DAHDI RAS Application" , .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static char * | dahdi_app = "DAHDIRAS" |
static char * | dahdi_descrip |
static char * | dahdi_synopsis = "Executes DAHDI ISDN RAS application" |
static char * | zap_app = "ZapRAS" |
static char * | zap_descrip |
static char * | zap_synopsis = "Executes Zaptel ISDN RAS application" |
Definition in file app_dahdiras.c.
#define PPP_EXEC "/usr/sbin/pppd" |
#define PPP_MAX_ARGS 32 |
static void __reg_module | ( | void | ) | [static] |
Definition at line 305 of file app_dahdiras.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 305 of file app_dahdiras.c.
static int exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 230 of file app_dahdiras.c.
References ast_channel::_state, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strdupa, ast_verbose(), dahdi_chan_name, LOG_WARNING, option_verbose, run_ras(), VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.
00231 { 00232 int res=-1; 00233 char *args; 00234 struct ast_module_user *u; 00235 struct dahdi_params ztp; 00236 00237 if (!data) 00238 data = ""; 00239 00240 u = ast_module_user_add(chan); 00241 00242 args = ast_strdupa(data); 00243 00244 /* Answer the channel if it's not up */ 00245 if (chan->_state != AST_STATE_UP) 00246 ast_answer(chan); 00247 if (strcasecmp(chan->tech->type, dahdi_chan_name)) { 00248 if (option_verbose > 1) 00249 ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a %s channel\n", chan->name, dahdi_chan_name); 00250 sleep(2); 00251 } else { 00252 memset(&ztp, 0, sizeof(ztp)); 00253 if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &ztp)) { 00254 ast_log(LOG_WARNING, "Unable to get parameters\n"); 00255 } else if (ztp.sigtype != DAHDI_SIG_CLEAR) { 00256 if (option_verbose > 1) 00257 ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name); 00258 } else { 00259 /* Everything should be okay. Run PPP. */ 00260 if (option_verbose > 2) 00261 ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name); 00262 /* Execute RAS */ 00263 run_ras(chan, args); 00264 } 00265 } 00266 ast_module_user_remove(u); 00267 return res; 00268 }
static int exec_warn | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 270 of file app_dahdiras.c.
References ast_log(), dahdi_app, exec(), LOG_WARNING, and zap_app.
Referenced by load_module().
00271 { 00272 ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app); 00273 00274 return exec(chan, data); 00275 }
static int load_module | ( | void | ) | [static] |
Definition at line 292 of file app_dahdiras.c.
References ast_register_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_app, dahdi_chan_mode, dahdi_descrip, dahdi_synopsis, exec(), exec_warn(), zap_app, zap_descrip, and zap_synopsis.
00293 { 00294 int res = 0; 00295 00296 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00297 res |= ast_register_application(dahdi_app, exec, dahdi_synopsis, dahdi_descrip); 00298 } 00299 00300 res |= ast_register_application(zap_app, exec_warn, zap_synopsis, zap_descrip); 00301 00302 return res; 00303 }
static void run_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 171 of file app_dahdiras.c.
References ast_channel::_softhangup, ast_log(), ast_verbose(), errno, ast_channel::fds, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_verbose, spawn_ras(), VERBOSE_PREFIX_3, WEXITSTATUS, and WIFEXITED.
Referenced by exec().
00172 { 00173 pid_t pid; 00174 int status; 00175 int res; 00176 int signalled = 0; 00177 struct dahdi_bufferinfo savebi; 00178 int x; 00179 00180 res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi); 00181 if(res) { 00182 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name); 00183 return; 00184 } 00185 00186 pid = spawn_ras(chan, args); 00187 if (pid < 0) { 00188 ast_log(LOG_WARNING, "Failed to spawn RAS\n"); 00189 } else { 00190 for (;;) { 00191 res = wait4(pid, &status, WNOHANG, NULL); 00192 if (!res) { 00193 /* Check for hangup */ 00194 if (chan->_softhangup && !signalled) { 00195 ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid); 00196 kill(pid, SIGTERM); 00197 signalled=1; 00198 } 00199 /* Try again */ 00200 sleep(1); 00201 continue; 00202 } 00203 if (res < 0) { 00204 ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno)); 00205 } 00206 if (option_verbose > 2) { 00207 if (WIFEXITED(status)) { 00208 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status)); 00209 } else if (WIFSIGNALED(status)) { 00210 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n", 00211 chan->name, WTERMSIG(status)); 00212 } else { 00213 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name); 00214 } 00215 } 00216 /* Throw back into audio mode */ 00217 x = 1; 00218 ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x); 00219 00220 /* Restore saved values */ 00221 res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi); 00222 if (res < 0) { 00223 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name); 00224 } 00225 break; 00226 } 00227 } 00228 }
static pid_t spawn_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 90 of file app_dahdiras.c.
References ast_log(), ast_opt_high_priority, ast_set_priority(), ast_module_user::chan, ast_channel::fds, LOG_WARNING, PPP_EXEC, and PPP_MAX_ARGS.
Referenced by run_ras().
00091 { 00092 pid_t pid; 00093 int x; 00094 char *c; 00095 00096 char *argv[PPP_MAX_ARGS]; 00097 int argc = 0; 00098 char *stringp=NULL; 00099 sigset_t fullset, oldset; 00100 #ifdef HAVE_CAP 00101 cap_t cap; 00102 #endif 00103 00104 sigfillset(&fullset); 00105 pthread_sigmask(SIG_BLOCK, &fullset, &oldset); 00106 00107 /* Start by forking */ 00108 pid = fork(); 00109 if (pid) { 00110 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00111 return pid; 00112 } 00113 00114 #ifdef HAVE_CAP 00115 cap = cap_from_text("cap_net_admin-eip"); 00116 00117 if (cap_set_proc(cap)) { 00118 /* Careful with order! Logging cannot happen after we close FDs */ 00119 ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); 00120 } 00121 cap_free(cap); 00122 #endif 00123 00124 /* Restore original signal handlers */ 00125 for (x=0;x<NSIG;x++) 00126 signal(x, SIG_DFL); 00127 00128 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00129 00130 /* Execute RAS on File handles */ 00131 dup2(chan->fds[0], STDIN_FILENO); 00132 00133 /* Drop high priority */ 00134 if (ast_opt_high_priority) 00135 ast_set_priority(0); 00136 00137 /* Close other file descriptors */ 00138 for (x=STDERR_FILENO + 1;x<1024;x++) 00139 close(x); 00140 00141 /* Reset all arguments */ 00142 memset(argv, 0, sizeof(argv)); 00143 00144 /* First argument is executable, followed by standard 00145 arguments for DAHDI PPP */ 00146 argv[argc++] = PPP_EXEC; 00147 argv[argc++] = "nodetach"; 00148 00149 /* And all the other arguments */ 00150 stringp=args; 00151 c = strsep(&stringp, "|"); 00152 while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) { 00153 argv[argc++] = c; 00154 c = strsep(&stringp, "|"); 00155 } 00156 00157 argv[argc++] = "plugin"; 00158 #ifdef HAVE_ZAPTEL 00159 argv[argc++] = "zaptel.so"; 00160 #else 00161 argv[argc++] = "dahdi.so"; 00162 #endif 00163 argv[argc++] = "stdin"; 00164 00165 /* Finally launch PPP */ 00166 execv(PPP_EXEC, argv); 00167 fprintf(stderr, "Failed to exec PPPD!\n"); 00168 exit(1); 00169 }
static int unload_module | ( | void | ) | [static] |
Definition at line 277 of file app_dahdiras.c.
References ast_module_user_hangup_all, ast_unregister_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_app, dahdi_chan_mode, and zap_app.
00278 { 00279 int res = 0; 00280 00281 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00282 res |= ast_unregister_application(dahdi_app); 00283 } 00284 00285 res |= ast_unregister_application(zap_app); 00286 00287 ast_module_user_hangup_all(); 00288 00289 return res; 00290 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "DAHDI RAS Application" , .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 305 of file app_dahdiras.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 305 of file app_dahdiras.c.
char* dahdi_app = "DAHDIRAS" [static] |
Definition at line 67 of file app_dahdiras.c.
char* dahdi_descrip [static] |
Definition at line 73 of file app_dahdiras.c.
char* dahdi_synopsis = "Executes DAHDI ISDN RAS application" [static] |
Definition at line 70 of file app_dahdiras.c.
char* zap_app = "ZapRAS" [static] |
Definition at line 68 of file app_dahdiras.c.
char* zap_descrip [static] |
Definition at line 80 of file app_dahdiras.c.
char* zap_synopsis = "Executes Zaptel ISDN RAS application" [static] |
Definition at line 71 of file app_dahdiras.c.