#include "asterisk.h"
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <dahdi/user.h>
#include <fcntl.h>
#include <sys/capability.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.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 | dahdiras_exec (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 , .description = "DAHDI ISDN Remote Access Server" , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static char * | app = "DAHDIRAS" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static char * | descrip |
static char * | synopsis = "Executes DAHDI 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 252 of file app_dahdiras.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 252 of file app_dahdiras.c.
static int dahdiras_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 207 of file app_dahdiras.c.
References ast_channel::_state, ast_answer(), ast_log(), AST_STATE_UP, ast_strdupa, ast_verb, chan, LOG_WARNING, and run_ras().
Referenced by load_module().
00208 { 00209 int res=-1; 00210 char *args; 00211 struct dahdi_params dahdip; 00212 00213 if (!data) 00214 data = ""; 00215 00216 args = ast_strdupa(data); 00217 00218 /* Answer the channel if it's not up */ 00219 if (chan->_state != AST_STATE_UP) 00220 ast_answer(chan); 00221 if (strcasecmp(chan->tech->type, "DAHDI")) { 00222 /* If it's not a DAHDI channel, we're done. Wait a couple of 00223 seconds and then hangup... */ 00224 ast_verb(2, "Channel %s is not a DAHDI channel\n", chan->name); 00225 sleep(2); 00226 } else { 00227 memset(&dahdip, 0, sizeof(dahdip)); 00228 if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip)) { 00229 ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n"); 00230 } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) { 00231 ast_verb(2, "Channel %s is not a clear channel\n", chan->name); 00232 } else { 00233 /* Everything should be okay. Run PPP. */ 00234 ast_verb(3, "Starting RAS on %s\n", chan->name); 00235 /* Execute RAS */ 00236 run_ras(chan, args); 00237 } 00238 } 00239 return res; 00240 }
static int load_module | ( | void | ) | [static] |
Definition at line 247 of file app_dahdiras.c.
References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application, and dahdiras_exec().
00248 { 00249 return ((ast_register_application(app, dahdiras_exec, synopsis, descrip)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS); 00250 }
static void run_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 150 of file app_dahdiras.c.
References ast_check_hangup(), ast_debug, ast_log(), ast_verb, chan, errno, ast_channel::fds, LOG_WARNING, ast_channel::name, spawn_ras(), status, WEXITSTATUS, and WIFEXITED.
Referenced by dahdiras_exec().
00151 { 00152 pid_t pid; 00153 int status; 00154 int res; 00155 int signalled = 0; 00156 struct dahdi_bufferinfo savebi; 00157 int x; 00158 00159 res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi); 00160 if(res) { 00161 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name); 00162 return; 00163 } 00164 00165 pid = spawn_ras(chan, args); 00166 if (pid < 0) { 00167 ast_log(LOG_WARNING, "Failed to spawn RAS\n"); 00168 } else { 00169 for (;;) { 00170 res = wait4(pid, &status, WNOHANG, NULL); 00171 if (!res) { 00172 /* Check for hangup */ 00173 if (ast_check_hangup(chan) && !signalled) { 00174 ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid); 00175 kill(pid, SIGTERM); 00176 signalled=1; 00177 } 00178 /* Try again */ 00179 sleep(1); 00180 continue; 00181 } 00182 if (res < 0) { 00183 ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno)); 00184 } 00185 if (WIFEXITED(status)) { 00186 ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status)); 00187 } else if (WIFSIGNALED(status)) { 00188 ast_verb(3, "RAS on %s terminated with signal %d\n", 00189 chan->name, WTERMSIG(status)); 00190 } else { 00191 ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name); 00192 } 00193 /* Throw back into audio mode */ 00194 x = 1; 00195 ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x); 00196 00197 /* Restore saved values */ 00198 res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi); 00199 if (res < 0) { 00200 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name); 00201 } 00202 break; 00203 } 00204 } 00205 }
static pid_t spawn_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 73 of file app_dahdiras.c.
References ast_log(), ast_opt_high_priority, ast_set_priority(), chan, ast_channel::fds, LOG_WARNING, PPP_EXEC, PPP_MAX_ARGS, and strsep().
Referenced by run_ras().
00074 { 00075 pid_t pid; 00076 int x; 00077 char *c; 00078 00079 char *argv[PPP_MAX_ARGS]; 00080 int argc = 0; 00081 char *stringp=NULL; 00082 sigset_t fullset, oldset; 00083 #ifdef HAVE_CAP 00084 cap_t cap; 00085 #endif 00086 00087 sigfillset(&fullset); 00088 pthread_sigmask(SIG_BLOCK, &fullset, &oldset); 00089 00090 /* Start by forking */ 00091 pid = fork(); 00092 if (pid) { 00093 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00094 return pid; 00095 } 00096 00097 #ifdef HAVE_CAP 00098 cap = cap_from_text("cap_net_admin-eip"); 00099 00100 if (cap_set_proc(cap)) { 00101 /* Careful with order! Logging cannot happen after we close FDs */ 00102 ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); 00103 } 00104 cap_free(cap); 00105 #endif 00106 00107 /* Restore original signal handlers */ 00108 for (x=0;x<NSIG;x++) 00109 signal(x, SIG_DFL); 00110 00111 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00112 00113 /* Execute RAS on File handles */ 00114 dup2(chan->fds[0], STDIN_FILENO); 00115 00116 /* Drop high priority */ 00117 if (ast_opt_high_priority) 00118 ast_set_priority(0); 00119 00120 /* Close other file descriptors */ 00121 for (x=STDERR_FILENO + 1;x<1024;x++) 00122 close(x); 00123 00124 /* Reset all arguments */ 00125 memset(argv, 0, sizeof(argv)); 00126 00127 /* First argument is executable, followed by standard 00128 arguments for dahdi PPP */ 00129 argv[argc++] = PPP_EXEC; 00130 argv[argc++] = "nodetach"; 00131 00132 /* And all the other arguments */ 00133 stringp=args; 00134 c = strsep(&stringp, ","); 00135 while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) { 00136 argv[argc++] = c; 00137 c = strsep(&stringp, ","); 00138 } 00139 00140 argv[argc++] = "plugin"; 00141 argv[argc++] = "dahdi.so"; 00142 argv[argc++] = "stdin"; 00143 00144 /* Finally launch PPP */ 00145 execv(PPP_EXEC, argv); 00146 fprintf(stderr, "Failed to exec PPPD!\n"); 00147 exit(1); 00148 }
static int unload_module | ( | void | ) | [static] |
Definition at line 242 of file app_dahdiras.c.
References ast_unregister_application().
00243 { 00244 return ast_unregister_application(app); 00245 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "DAHDI ISDN Remote Access Server" , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 252 of file app_dahdiras.c.
char* app = "DAHDIRAS" [static] |
Definition at line 58 of file app_dahdiras.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 252 of file app_dahdiras.c.
char* descrip [static] |
Definition at line 62 of file app_dahdiras.c.
char* synopsis = "Executes DAHDI ISDN RAS application" [static] |
Definition at line 60 of file app_dahdiras.c.