RADIUS CDR Support. More...
#include "asterisk.h"
#include <radiusclient-ng.h>
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Defines | |
#define | DATE_FORMAT "%Y-%m-%d %T %z" |
#define | VENDOR_CODE 22736 |
Enumerations | |
enum | { PW_AST_ACCT_CODE = 101, PW_AST_SRC = 102, PW_AST_DST = 103, PW_AST_DST_CTX = 104, PW_AST_CLID = 105, PW_AST_CHAN = 106, PW_AST_DST_CHAN = 107, PW_AST_LAST_APP = 108, PW_AST_LAST_DATA = 109, PW_AST_START_TIME = 110, PW_AST_ANSWER_TIME = 111, PW_AST_END_TIME = 112, PW_AST_DURATION = 113, PW_AST_BILL_SEC = 114, PW_AST_DISPOSITION = 115, PW_AST_AMA_FLAGS = 116, PW_AST_UNIQUE_ID = 117, PW_AST_USER_FIELD = 118 } |
enum | { RADIUS_FLAG_USEGMTIME = (1 << 0), RADIUS_FLAG_LOGUNIQUEID = (1 << 1), RADIUS_FLAG_LOGUSERFIELD = (1 << 2) } |
Functions | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"RADIUS CDR Backend",.load=load_module,.unload=unload_module,.load_pri=AST_MODPRI_CDR_DRIVER,) | |
static int | build_radius_record (VALUE_PAIR **tosend, struct ast_cdr *cdr) |
static int | load_module (void) |
static int | radius_log (struct ast_cdr *cdr) |
static int | unload_module (void) |
Variables | |
static const char | cdr_config [] = "cdr.conf" |
static const char | desc [] = "RADIUS CDR Backend" |
static struct ast_flags | global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD } |
static const char | name [] = "radius" |
static char | radiuscfg [PATH_MAX] = "/etc/radiusclient-ng/radiusclient.conf" |
static rc_handle * | rh = NULL |
RADIUS CDR Support.
Definition in file cdr_radius.c.
#define DATE_FORMAT "%Y-%m-%d %T %z" |
ISO 8601 standard format
Definition at line 47 of file cdr_radius.c.
#define VENDOR_CODE 22736 |
Definition at line 49 of file cdr_radius.c.
Referenced by build_radius_record().
anonymous enum |
Definition at line 51 of file cdr_radius.c.
00051 { 00052 PW_AST_ACCT_CODE = 101, 00053 PW_AST_SRC = 102, 00054 PW_AST_DST = 103, 00055 PW_AST_DST_CTX = 104, 00056 PW_AST_CLID = 105, 00057 PW_AST_CHAN = 106, 00058 PW_AST_DST_CHAN = 107, 00059 PW_AST_LAST_APP = 108, 00060 PW_AST_LAST_DATA = 109, 00061 PW_AST_START_TIME = 110, 00062 PW_AST_ANSWER_TIME = 111, 00063 PW_AST_END_TIME = 112, 00064 PW_AST_DURATION = 113, 00065 PW_AST_BILL_SEC = 114, 00066 PW_AST_DISPOSITION = 115, 00067 PW_AST_AMA_FLAGS = 116, 00068 PW_AST_UNIQUE_ID = 117, 00069 PW_AST_USER_FIELD = 118 00070 };
anonymous enum |
RADIUS_FLAG_USEGMTIME |
Log dates and times in UTC |
RADIUS_FLAG_LOGUNIQUEID |
Log Unique ID |
RADIUS_FLAG_LOGUSERFIELD |
Log User Field |
Definition at line 72 of file cdr_radius.c.
00072 { 00073 /*! Log dates and times in UTC */ 00074 RADIUS_FLAG_USEGMTIME = (1 << 0), 00075 /*! Log Unique ID */ 00076 RADIUS_FLAG_LOGUNIQUEID = (1 << 1), 00077 /*! Log User Field */ 00078 RADIUS_FLAG_LOGUSERFIELD = (1 << 2) 00079 };
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_LOAD_ORDER | , | |||
"RADIUS CDR Backend" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | load_pri = AST_MODPRI_CDR_DRIVER | |||
) |
static int build_radius_record | ( | VALUE_PAIR ** | tosend, | |
struct ast_cdr * | cdr | |||
) | [static] |
Definition at line 91 of file cdr_radius.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_localtime(), ast_strftime(), ast_test_flag, ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, PW_AST_ACCT_CODE, PW_AST_AMA_FLAGS, PW_AST_ANSWER_TIME, PW_AST_BILL_SEC, PW_AST_CHAN, PW_AST_CLID, PW_AST_DISPOSITION, PW_AST_DST, PW_AST_DST_CHAN, PW_AST_DST_CTX, PW_AST_DURATION, PW_AST_END_TIME, PW_AST_LAST_APP, PW_AST_LAST_DATA, PW_AST_SRC, PW_AST_START_TIME, PW_AST_UNIQUE_ID, PW_AST_USER_FIELD, RADIUS_FLAG_LOGUNIQUEID, RADIUS_FLAG_LOGUSERFIELD, RADIUS_FLAG_USEGMTIME, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, ast_cdr::userfield, and VENDOR_CODE.
Referenced by radius_log().
00092 { 00093 int recordtype = PW_STATUS_STOP; 00094 struct ast_tm tm; 00095 char timestr[128]; 00096 char *tmp; 00097 00098 if (!rc_avpair_add(rh, tosend, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0)) 00099 return -1; 00100 00101 /* Account code */ 00102 if (!rc_avpair_add(rh, tosend, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE)) 00103 return -1; 00104 00105 /* Source */ 00106 if (!rc_avpair_add(rh, tosend, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE)) 00107 return -1; 00108 00109 /* Destination */ 00110 if (!rc_avpair_add(rh, tosend, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE)) 00111 return -1; 00112 00113 /* Destination context */ 00114 if (!rc_avpair_add(rh, tosend, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE)) 00115 return -1; 00116 00117 /* Caller ID */ 00118 if (!rc_avpair_add(rh, tosend, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE)) 00119 return -1; 00120 00121 /* Channel */ 00122 if (!rc_avpair_add(rh, tosend, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE)) 00123 return -1; 00124 00125 /* Destination Channel */ 00126 if (!rc_avpair_add(rh, tosend, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE)) 00127 return -1; 00128 00129 /* Last Application */ 00130 if (!rc_avpair_add(rh, tosend, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE)) 00131 return -1; 00132 00133 /* Last Data */ 00134 if (!rc_avpair_add(rh, tosend, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE)) 00135 return -1; 00136 00137 00138 /* Start Time */ 00139 ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, 00140 ast_localtime(&cdr->start, &tm, 00141 ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL)); 00142 if (!rc_avpair_add(rh, tosend, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE)) 00143 return -1; 00144 00145 /* Answer Time */ 00146 ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, 00147 ast_localtime(&cdr->answer, &tm, 00148 ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL)); 00149 if (!rc_avpair_add(rh, tosend, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE)) 00150 return -1; 00151 00152 /* End Time */ 00153 ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, 00154 ast_localtime(&cdr->end, &tm, 00155 ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL)); 00156 if (!rc_avpair_add(rh, tosend, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE)) 00157 return -1; 00158 00159 /* Duration */ 00160 if (!rc_avpair_add(rh, tosend, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE)) 00161 return -1; 00162 00163 /* Billable seconds */ 00164 if (!rc_avpair_add(rh, tosend, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE)) 00165 return -1; 00166 00167 /* Disposition */ 00168 tmp = ast_cdr_disp2str(cdr->disposition); 00169 if (!rc_avpair_add(rh, tosend, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE)) 00170 return -1; 00171 00172 /* AMA Flags */ 00173 tmp = ast_cdr_flags2str(cdr->amaflags); 00174 if (!rc_avpair_add(rh, tosend, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE)) 00175 return -1; 00176 00177 if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) { 00178 /* Unique ID */ 00179 if (!rc_avpair_add(rh, tosend, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE)) 00180 return -1; 00181 } 00182 00183 if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) { 00184 /* append the user field */ 00185 if (!rc_avpair_add(rh, tosend, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE)) 00186 return -1; 00187 } 00188 00189 /* Setting Acct-Session-Id & User-Name attributes for proper generation 00190 of Acct-Unique-Session-Id on server side */ 00191 /* Channel */ 00192 if (!rc_avpair_add(rh, tosend, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0)) 00193 return -1; 00194 00195 /* Unique ID */ 00196 if (!rc_avpair_add(rh, tosend, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0)) 00197 return -1; 00198 00199 return 0; 00200 }
static int load_module | ( | void | ) | [static] |
Definition at line 235 of file cdr_radius.c.
References ast_cdr_register(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_set2_flag, ast_strdup, ast_true(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, LOG_NOTICE, RADIUS_FLAG_LOGUNIQUEID, RADIUS_FLAG_LOGUSERFIELD, RADIUS_FLAG_USEGMTIME, and radius_log().
00236 { 00237 struct ast_config *cfg; 00238 struct ast_flags config_flags = { 0 }; 00239 const char *tmp; 00240 00241 if ((cfg = ast_config_load(cdr_config, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 00242 ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "usegmtime")), RADIUS_FLAG_USEGMTIME); 00243 ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguniqueid")), RADIUS_FLAG_LOGUNIQUEID); 00244 ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguserfield")), RADIUS_FLAG_LOGUSERFIELD); 00245 if ((tmp = ast_variable_retrieve(cfg, "radius", "radiuscfg"))) 00246 ast_copy_string(radiuscfg, tmp, sizeof(radiuscfg)); 00247 ast_config_destroy(cfg); 00248 } else 00249 return AST_MODULE_LOAD_DECLINE; 00250 00251 /* 00252 * start logging 00253 * 00254 * NOTE: Yes this causes a slight memory leak if the module is 00255 * unloaded. However, it is better than a crash if cdr_radius 00256 * and cel_radius are both loaded. 00257 */ 00258 tmp = ast_strdup("asterisk"); 00259 if (tmp) { 00260 rc_openlog((char *) tmp); 00261 } 00262 00263 /* read radiusclient-ng config file */ 00264 if (!(rh = rc_read_config(radiuscfg))) { 00265 ast_log(LOG_NOTICE, "Cannot load radiusclient-ng configuration file %s.\n", radiuscfg); 00266 return AST_MODULE_LOAD_DECLINE; 00267 } 00268 00269 /* read radiusclient-ng dictionaries */ 00270 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) { 00271 ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n"); 00272 rc_destroy(rh); 00273 rh = NULL; 00274 return AST_MODULE_LOAD_DECLINE; 00275 } 00276 00277 if (ast_cdr_register(name, desc, radius_log)) { 00278 rc_destroy(rh); 00279 rh = NULL; 00280 return AST_MODULE_LOAD_DECLINE; 00281 } else { 00282 return AST_MODULE_LOAD_SUCCESS; 00283 } 00284 }
static int radius_log | ( | struct ast_cdr * | cdr | ) | [static] |
Definition at line 202 of file cdr_radius.c.
References ast_debug, ast_log(), build_radius_record(), and LOG_ERROR.
Referenced by load_module().
00203 { 00204 int result = ERROR_RC; 00205 VALUE_PAIR *tosend = NULL; 00206 00207 if (build_radius_record(&tosend, cdr)) { 00208 ast_debug(1, "Unable to create RADIUS record. CDR not recorded!\n"); 00209 goto return_cleanup; 00210 } 00211 00212 result = rc_acct(rh, 0, tosend); 00213 if (result != OK_RC) { 00214 ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n"); 00215 } 00216 00217 return_cleanup: 00218 if (tosend) { 00219 rc_avpair_free(tosend); 00220 } 00221 00222 return result; 00223 }
static int unload_module | ( | void | ) | [static] |
Definition at line 225 of file cdr_radius.c.
References ast_cdr_unregister().
00226 { 00227 ast_cdr_unregister(name); 00228 if (rh) { 00229 rc_destroy(rh); 00230 rh = NULL; 00231 } 00232 return 0; 00233 }
const char cdr_config[] = "cdr.conf" [static] |
Definition at line 83 of file cdr_radius.c.
const char desc[] = "RADIUS CDR Backend" [static] |
Definition at line 81 of file cdr_radius.c.
Referenced by acf_retrieve_docs(), ast_data_add_codecs(), ast_tcptls_client_start(), ast_tcptls_server_root(), AST_TEST_DEFINE(), dump_cause(), handle_cli_ulimit(), init_acf_query(), misdn_cfg_get_desc(), ogg_vorbis_open(), ogg_vorbis_read(), ogg_vorbis_seek(), ogg_vorbis_tell(), show_config_description(), and str2desc().
struct ast_flags global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD } [static] |
Definition at line 87 of file cdr_radius.c.
const char name[] = "radius" [static] |
Definition at line 82 of file cdr_radius.c.
char radiuscfg[PATH_MAX] = "/etc/radiusclient-ng/radiusclient.conf" [static] |
Definition at line 85 of file cdr_radius.c.
rc_handle* rh = NULL [static] |
Definition at line 89 of file cdr_radius.c.
Referenced by handle_response().