00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <time.h>
00035 #include <radiusclient-ng.h>
00036 #include "../../rad_dict.h"
00037
00038 #include "../../sr_module.h"
00039 #include "../../dprint.h"
00040 #include "../../mem/mem.h"
00041 #include "../../modules/tm/t_hooks.h"
00042 #include "../../modules/tm/tm_load.h"
00043 #include "../../modules/tm/h_table.h"
00044 #include "../../parser/msg_parser.h"
00045 #include "../../parser/parse_from.h"
00046 #include "../../parser/digest/digest.h"
00047 #include "../../usr_avp.h"
00048 #include "../../id.h"
00049 #include "../../modules/tm/tm_load.h"
00050
00051 #include "../../parser/parse_rr.h"
00052 #include "../../trim.h"
00053 #include "../acc_syslog/attrs.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #define ALL_LOG_FMT "acdfgimnoprstuxDFIMPRSTUX"
00096 #define ALL_LOG_FMT_LEN (sizeof(ALL_LOG_FMT) - 1)
00097
00098 MODULE_VERSION
00099
00100 struct tm_binds tmb;
00101
00102 static int mod_init( void );
00103 static int fix_log_flag( modparam_t type, void* val);
00104 static int fix_log_missed_flag( modparam_t type, void* val);
00105
00106 static int early_media = 0;
00107 static int failed_transactions = 0;
00108 static int report_cancels = 0;
00109 static int report_ack = 0;
00110 static int log_flag = 0;
00111 static int log_missed_flag = 0;
00112 static char* log_fmt = ALL_LOG_FMT;
00113
00114
00115 static char* attrs_param = "";
00116 avp_ident_t* avps;
00117 int avps_n;
00118
00119 static char *radius_config = "/usr/local/etc/radiusclient-ng/radiusclient.conf";
00120 static int service_type = -1;
00121 static int swap_dir = 0;
00122
00123 static void *rh;
00124 static struct attr attrs[A_MAX];
00125 static struct val vals[V_MAX];
00126
00127 static int acc_rad_request0(struct sip_msg *rq, char *p1, char *p2);
00128 static int acc_rad_missed0(struct sip_msg *rq, char *p1, char *p2);
00129 static int acc_rad_request1(struct sip_msg *rq, char *p1, char *p2);
00130 static int acc_rad_missed1(struct sip_msg *rq, char *p1, char *p2);
00131
00132 static cmd_export_t cmds[] = {
00133 {"acc_rad_log", acc_rad_request0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
00134 {"acc_rad_missed", acc_rad_missed0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
00135 {"acc_rad_log", acc_rad_request1, 1, fixup_var_int_1, REQUEST_ROUTE | FAILURE_ROUTE},
00136 {"acc_rad_missed", acc_rad_missed1, 1, fixup_var_int_1, REQUEST_ROUTE | FAILURE_ROUTE},
00137 {0, 0, 0, 0, 0}
00138 };
00139
00140
00141 static param_export_t params[] = {
00142 {"early_media", PARAM_INT, &early_media },
00143 {"failed_transactions", PARAM_INT, &failed_transactions },
00144 {"report_ack", PARAM_INT, &report_ack },
00145 {"report_cancels", PARAM_INT, &report_cancels },
00146 {"log_flag", PARAM_INT, &log_flag },
00147 {"log_flag", PARAM_STRING|PARAM_USE_FUNC, fix_log_flag},
00148 {"log_missed_flag", PARAM_INT, &log_missed_flag },
00149 {"log_missed_flag", PARAM_STRING|PARAM_USE_FUNC, fix_log_missed_flag},
00150 {"log_fmt", PARAM_STRING, &log_fmt },
00151 {"attrs", PARAM_STRING, &attrs_param },
00152 {"radius_config", PARAM_STRING, &radius_config },
00153 {"service_type", PARAM_INT, &service_type },
00154 {"swap_direction", PARAM_INT, &swap_dir },
00155 {0, 0, 0}
00156 };
00157
00158
00159 struct module_exports exports= {
00160 "acc_radius",
00161 cmds,
00162 0,
00163 params,
00164 mod_init,
00165 0,
00166 0,
00167 0,
00168 0
00169 };
00170
00171
00172
00173
00174 static int fix_log_flag( modparam_t type, void* val)
00175 {
00176 return fix_flag(type, val, "acc_radius", "log_flag", &log_flag);
00177 }
00178
00179
00180
00181
00182 static int fix_log_missed_flag( modparam_t type, void* val)
00183 {
00184 return fix_flag(type, val, "acc_radius", "log_missed_flag", &log_missed_flag);
00185 }
00186
00187
00188
00189 static inline int skip_cancel(struct sip_msg *msg)
00190 {
00191 return (msg->REQ_METHOD == METHOD_CANCEL) && report_cancels == 0;
00192 }
00193
00194 static int check_ftag(struct sip_msg* msg, str* uri)
00195 {
00196 param_hooks_t hooks;
00197 param_t* params;
00198 char* semi;
00199 struct to_body* from;
00200 str t;
00201
00202 t = *uri;
00203 params = 0;
00204 semi = q_memchr(t.s, ';', t.len);
00205 if (!semi) {
00206 DBG("No ftag parameter found\n");
00207 return -1;
00208 }
00209
00210 t.len -= semi - uri->s + 1;
00211 t.s = semi + 1;
00212 trim_leading(&t);
00213
00214 if (parse_params(&t, CLASS_URI, &hooks, ¶ms) < 0) {
00215 ERR("Error while parsing parameters\n");
00216 return -1;
00217 }
00218
00219 if (!hooks.uri.ftag) {
00220 DBG("No ftag parameter found\n");
00221 goto err;
00222 }
00223
00224 from = get_from(msg);
00225
00226 if (!from || !from->tag_value.len || !from->tag_value.s) {
00227 DBG("No from tag parameter found\n");
00228 goto err;
00229 }
00230
00231 if (from->tag_value.len == hooks.uri.ftag->body.len &&
00232 !strncmp(from->tag_value.s, hooks.uri.ftag->body.s, hooks.uri.ftag->body.len)) {
00233 DBG("Route ftag and From tag are same\n");
00234 free_params(params);
00235 return 0;
00236 } else {
00237 DBG("Route ftag and From tag are NOT same\n");
00238 free_params(params);
00239 return 1;
00240 }
00241
00242 err:
00243 if (params) free_params(params);
00244 return -1;
00245 }
00246
00247 static int get_direction(struct sip_msg* msg)
00248 {
00249 int ret;
00250 if (parse_orig_ruri(msg) < 0) {
00251 return -1;
00252 }
00253
00254 if (!msg->parsed_orig_ruri_ok) {
00255 ERR("Error while parsing original Request-URI\n");
00256 return -1;
00257 }
00258
00259 ret = check_self(&msg->parsed_orig_ruri.host,
00260 msg->parsed_orig_ruri.port_no ? msg->parsed_orig_ruri.port_no : SIP_PORT, 0);
00261 if (ret < 0) return -1;
00262 if (ret > 0) {
00263
00264 return check_ftag(msg, &msg->first_line.u.request.uri);
00265 } else {
00266 if (msg->route) {
00267 if (parse_rr(msg->route) < 0) {
00268 ERR("Error while parsing Route HF\n");
00269 return -1;
00270 }
00271 ret = check_ftag(msg, &((rr_t*)msg->route->parsed)->nameaddr.uri);
00272 if (msg->route->parsed) free_rr((rr_t**)(void*)&msg->route->parsed);
00273 return ret;
00274 } else {
00275 DBG("No Route headers found\n");
00276 return -1;
00277 }
00278 }
00279 }
00280
00281
00282 int verify_fmt(char *fmt) {
00283
00284 if (!fmt) {
00285 LOG(L_ERR, "ERROR:acc:verify_fmt: formatting string zero\n");
00286 return -1;
00287 }
00288
00289 if (!(*fmt)) {
00290 LOG(L_ERR, "ERROR:acc:verify_fmt: formatting string empty\n");
00291 return -1;
00292 }
00293
00294 if (strlen(fmt) > ALL_LOG_FMT_LEN) {
00295 LOG(L_ERR, "ERROR:acc:verify_fmt: formatting string too long\n");
00296 return -1;
00297 }
00298
00299 while(*fmt) {
00300 if (!strchr(ALL_LOG_FMT, *fmt)) {
00301 LOG(L_ERR, "ERROR:acc:verify_fmt: char in log_fmt invalid: %c\n", *fmt);
00302 return -1;
00303 }
00304 fmt++;
00305 }
00306 return 1;
00307 }
00308
00309
00310
00311
00312
00313
00314 static inline int is_acc_on(struct sip_msg *rq)
00315 {
00316 return log_flag && isflagset(rq, log_flag) == 1;
00317 }
00318
00319
00320
00321
00322
00323
00324 static inline int is_mc_on(struct sip_msg *rq)
00325 {
00326 return log_missed_flag && isflagset(rq, log_missed_flag) == 1;
00327 }
00328
00329
00330 static inline void preparse_req(struct sip_msg *rq)
00331 {
00332
00333
00334
00335
00336
00337
00338 parse_headers(rq, HDR_CALLID_F | HDR_FROM_F | HDR_TO_F | HDR_CSEQ_F | HDR_ROUTE_F, 0 );
00339 parse_from_header(rq);
00340 }
00341
00342
00343
00344 static inline int should_acc_reply(struct cell* t, int code)
00345 {
00346 struct sip_msg *r;
00347
00348 r = t->uas.request;
00349
00350
00351 if (r == 0) {
00352 LOG(L_ERR, "ERROR:acc:should_acc_reply: 0 request\n");
00353 return 0;
00354 }
00355
00356
00357
00358 if (!failed_transactions && code >= 300) return 0;
00359 if (!is_acc_on(r)) return 0;
00360 if (skip_cancel(r)) return 0;
00361 if (code < 200 && ! (early_media && code == 183)) return 0;
00362 return 1;
00363 }
00364
00365
00366
00367 static inline str* cred_user(struct sip_msg* rq)
00368 {
00369 struct hdr_field* h;
00370 auth_body_t* cred;
00371
00372 get_authorized_cred(rq->proxy_auth, &h);
00373 if (!h) get_authorized_cred(rq->authorization, &h);
00374 if (!h) return 0;
00375 cred = (auth_body_t*)(h->parsed);
00376 if (!cred || !cred->digest.username.user.len)
00377 return 0;
00378 return &cred->digest.username.user;
00379 }
00380
00381
00382
00383 static inline str* cred_realm(struct sip_msg* rq)
00384 {
00385 str* realm;
00386 struct hdr_field* h;
00387 auth_body_t* cred;
00388
00389 get_authorized_cred(rq->proxy_auth, &h);
00390 if (!h) get_authorized_cred(rq->authorization, &h);
00391 if (!h) return 0;
00392 cred = (auth_body_t*)(h->parsed);
00393 if (!cred) return 0;
00394 realm = GET_REALM(&cred->digest);
00395 if (!realm->len || !realm->s) {
00396 return 0;
00397 }
00398 return realm;
00399 }
00400
00401
00402
00403
00404
00405 static inline struct hdr_field* valid_to(struct cell* t, struct sip_msg* reply)
00406 {
00407 if (reply == FAKED_REPLY || !reply || !reply->to) {
00408 return t->uas.request->to;
00409 } else {
00410 return reply->to;
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421 static int fmt2rad(char *fmt,
00422 struct sip_msg *rq,
00423 str* ouri,
00424 struct hdr_field *to,
00425 unsigned int code,
00426 VALUE_PAIR** send,
00427 time_t req_time)
00428 {
00429 static unsigned int cseq_num, src_port, src_ip;
00430 static time_t rq_time, rs_time;
00431 int cnt;
00432 struct to_body* from, *pto;
00433 str val, *cr, *at;
00434 struct cseq_body *cseq;
00435 struct attr* attr;
00436 int dir;
00437
00438 cnt = 0;
00439 dir = -2;
00440
00441
00442
00443
00444
00445
00446 while(*fmt) {
00447 if (cnt == ALL_LOG_FMT_LEN) {
00448 LOG(L_ERR, "ERROR:acc:fmt2rad: Formatting string is too long\n");
00449 return 0;
00450 }
00451
00452 attr = 0;
00453 switch(*fmt) {
00454 case 'a':
00455 at = print_attrs(avps, avps_n, 0);
00456 if (at) {
00457 attr = &attrs[A_SER_ATTR];
00458 val = *at;
00459 }
00460 break;
00461
00462 case 'c':
00463 if (rq->callid && rq->callid->body.len) {
00464 attr = &attrs[A_ACCT_SESSION_ID];
00465 val = rq->callid->body;
00466 }
00467 break;
00468
00469 case 'd':
00470 if (swap_dir && dir == -2) dir = get_direction(rq);
00471 if (dir <= 0) {
00472 if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) {
00473 attr = &attrs[A_SIP_TO_TAG];
00474 val = pto->tag_value;
00475 }
00476 } else {
00477 if (rq->from && (from = get_from(rq)) && from->tag_value.len) {
00478 attr = &attrs[A_SIP_TO_TAG];
00479 val = from->tag_value;
00480 }
00481 }
00482 break;
00483
00484 case 'f':
00485 if (rq->from && rq->from->body.len) {
00486 attr = &attrs[A_SER_FROM];
00487 val = rq->from->body;
00488 }
00489 break;
00490
00491 case 'g':
00492 attr = &attrs[A_SER_FLAGS];
00493 val.s = (char*)&rq->flags;
00494 val.len = sizeof(unsigned int);
00495 break;
00496
00497 case 'i':
00498 attr = &attrs[A_SER_ORIGINAL_REQUEST_ID];
00499 val = rq->first_line.u.request.uri;
00500 break;
00501
00502 case 'm':
00503 attr = &attrs[A_SIP_METHOD];
00504 val = rq->first_line.u.request.method;
00505 break;
00506
00507 case 'n':
00508 if (rq->cseq && (cseq = get_cseq(rq)) && cseq->number.len) {
00509 attr = &attrs[A_SIP_CSEQ];
00510 str2int(&cseq->number, &cseq_num);
00511 val.s = (char*)&cseq_num;
00512 val.len = sizeof(unsigned int);
00513 }
00514 break;
00515
00516 case 'o':
00517 attr = &attrs[A_SIP_TRANSLATED_REQUEST_ID];
00518 val = *ouri;
00519 break;
00520
00521 case 'p':
00522 attr = &attrs[A_SIP_SOURCE_IP_ADDRESS];
00523 src_ip = ntohl(rq->rcv.src_ip.u.addr32[0]);
00524 val.s = (char*)&src_ip;
00525 val.len = sizeof(src_ip);
00526 break;
00527
00528 case 'r':
00529 if (swap_dir && dir == -2) dir = get_direction(rq);
00530 if (dir <= 0) {
00531 if (rq->from && (from = get_from(rq)) && from->tag_value.len) {
00532 attr = &attrs[A_SIP_FROM_TAG];
00533 val = from->tag_value;
00534 }
00535 } else {
00536 if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) {
00537 attr = &attrs[A_SIP_FROM_TAG];
00538 val = pto->tag_value;
00539 }
00540 }
00541 break;
00542
00543 case 's':
00544 attr = &attrs[A_SER_SERVER_ID];
00545 val.s = (char*)&server_id;
00546 val.len = sizeof(int);
00547 break;
00548
00549 case 't':
00550 if (to && to->body.len) {
00551 attr = &attrs[A_SER_TO];
00552 val = to->body;
00553 }
00554 break;
00555
00556 case 'u':
00557 cr = cred_user(rq);
00558 if (cr) {
00559 attr = &attrs[A_SER_DIGEST_USERNAME];
00560 val = *cr;
00561 }
00562 break;
00563
00564 case 'x':
00565 attr = &attrs[A_SER_REQUEST_TIMESTAMP];
00566 rq_time = req_time;
00567 val.s = (char*)&rq_time;
00568 val.len = sizeof(time_t);
00569 break;
00570
00571 case 'D':
00572 break;
00573
00574 case 'F':
00575 if (swap_dir && dir == -2) dir = get_direction(rq);
00576 if (dir <= 0) {
00577 if (rq->from && (from = get_from(rq)) && from->uri.len) {
00578 attr = &attrs[A_CALLING_STATION_ID];
00579 val = from->uri;
00580 }
00581 } else {
00582 if (rq->to && (pto = get_to(rq)) && pto->uri.len) {
00583 attr = &attrs[A_CALLING_STATION_ID];
00584 val = pto->uri;
00585 }
00586 }
00587 break;
00588
00589 case 'I':
00590 if (get_from_uid(&val, rq) < 0) {
00591 attr = &attrs[A_SER_FROM_UID];
00592 }
00593 break;
00594
00595 case 'M':
00596 break;
00597
00598 case 'P':
00599 attr = &attrs[A_SIP_SOURCE_PORT];
00600 src_port = rq->rcv.src_port;
00601 val.s = (char*)&src_port;
00602 val.len = sizeof(unsigned int);
00603 break;
00604
00605 case 'R':
00606 cr = cred_realm(rq);
00607 if (cr) {
00608 attr = &attrs[A_SER_DIGEST_REALM];
00609 val = *cr;
00610 }
00611 break;
00612
00613 case 'S':
00614 attr = &attrs[A_SIP_RESPONSE_CODE];
00615 val.s = (char*)&code;
00616 val.len = sizeof(unsigned int);
00617 break;
00618
00619 case 'T':
00620 if (swap_dir && dir == -2) dir = get_direction(rq);
00621 if (dir <= 0) {
00622 if (rq->to && (pto = get_to(rq)) && pto->uri.len) {
00623 attr = &attrs[A_CALLED_STATION_ID];
00624 val = pto->uri;
00625 }
00626 } else {
00627 if (rq->from && (from = get_from(rq)) && from->uri.len) {
00628 attr = &attrs[A_CALLED_STATION_ID];
00629 val = from->uri;
00630 }
00631 }
00632 break;
00633
00634 case 'U':
00635 if (get_from_uid(&val, rq) < 0) {
00636 attr = &attrs[A_SER_TO_UID];
00637 }
00638 break;
00639
00640 case 'X':
00641 attr = &attrs[A_SER_RESPONSE_TIMESTAMP];
00642 rs_time = time(0);
00643 val.s = (char*)&rs_time;
00644 val.len = sizeof(time_t);
00645 break;
00646
00647 default:
00648 LOG(L_CRIT, "BUG:acc:fmt2rad: unknown char: %c\n", *fmt);
00649 return -1;
00650 }
00651
00652 if (attr) {
00653 if (!rc_avpair_add(rh, send, ATTRID(attr->v), val.s, val.len, VENDOR(attr->v))) {
00654 LOG(L_ERR, "ERROR:acc:fmt2rad: Failed to add attribute %s\n",
00655 attr->n);
00656 return -1;
00657 }
00658 }
00659
00660 fmt++;
00661 cnt++;
00662 }
00663
00664 return 0;
00665 }
00666
00667
00668
00669
00670
00671
00672 static inline UINT4 rad_status(struct sip_msg *rq, unsigned int code)
00673 {
00674
00675 if (code == 0) {
00676 return vals[V_FAILED].v;
00677 }
00678
00679
00680 if ((rq->REQ_METHOD == METHOD_INVITE || rq->REQ_METHOD == METHOD_ACK)
00681 && code >= 200 && code < 300) {
00682 return vals[V_START].v;
00683 }
00684
00685
00686 if ((rq->REQ_METHOD == METHOD_BYE || rq->REQ_METHOD == METHOD_CANCEL)) {
00687 return vals[V_STOP].v;
00688 }
00689
00690
00691 if (code >= 200 && code < 300) {
00692 return vals[V_INTERIM_UPDATE].v;
00693 }
00694
00695
00696 return vals[V_FAILED].v;
00697 }
00698
00699
00700
00701
00702
00703 static inline int add_user_name(struct sip_msg* rq, void* rh, VALUE_PAIR** send)
00704 {
00705 struct sip_uri puri;
00706 str* user, *realm;
00707 str user_name;
00708 struct to_body* from;
00709
00710 user = cred_user(rq);
00711 realm = cred_realm(rq);
00712
00713 if (!user || !realm) {
00714 if (rq->from && (from = get_from(rq)) && from->uri.len) {
00715 if (parse_uri(from->uri.s, from->uri.len, &puri) < 0 ) {
00716 LOG(L_ERR, "ERROR:acc:add_user_name: Bad From URI\n");
00717 return -1;
00718 }
00719
00720 user = &puri.user;
00721 realm = &puri.host;
00722 } else {
00723 DBG("acc:add_user_name: Neither digest nor From found, mandatory attribute User-Name not added\n");
00724 return -1;
00725 }
00726 }
00727
00728 user_name.len = user->len + 1 + realm->len;
00729 user_name.s = pkg_malloc(user_name.len);
00730 if (!user_name.s) {
00731 LOG(L_ERR, "ERROR:acc:add_user_name: no memory\n");
00732 return -1;
00733 }
00734 memcpy(user_name.s, user->s, user->len);
00735 user_name.s[user->len] = '@';
00736 memcpy(user_name.s + user->len + 1, realm->s, realm->len);
00737
00738 if (!rc_avpair_add(rh, send, ATTRID(attrs[A_USER_NAME].v),
00739 user_name.s, user_name.len, VENDOR(attrs[A_USER_NAME].v))) {
00740 LOG(L_ERR, "ERROR:acc:add_user_name: Failed to add User-Name attribute\n");
00741 pkg_free(user_name.s);
00742 return -1;
00743 }
00744 pkg_free(user_name.s);
00745
00746 return 0;
00747 }
00748
00749
00750
00751
00752
00753
00754
00755 static int log_request(struct sip_msg* rq, str* ouri, struct hdr_field* to, unsigned int code, time_t req_time)
00756 {
00757 VALUE_PAIR *send;
00758 UINT4 av_type;
00759
00760 send = NULL;
00761 if (skip_cancel(rq)) return 1;
00762
00763 if (fmt2rad(log_fmt, rq, ouri, to, code, &send, req_time) < 0) goto error;
00764
00765
00766 av_type = rad_status(rq, code);
00767 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_ACCT_STATUS_TYPE].v), &av_type, -1,
00768 VENDOR(attrs[A_ACCT_STATUS_TYPE].v))) {
00769 ERR("Add Status-Type\n");
00770 goto error;
00771 }
00772
00773
00774 av_type = (service_type != -1) ? service_type : vals[V_SIP_SESSION].v;
00775 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SERVICE_TYPE].v), &av_type, -1,
00776 VENDOR(attrs[A_SERVICE_TYPE].v))) {
00777 ERR("add STATUS_TYPE\n");
00778 goto error;
00779 }
00780
00781
00782 if (add_user_name(rq, rh, &send) < 0) goto error;
00783
00784
00785 if (rc_acct(rh, SIP_PORT, send) != OK_RC) {
00786 ERR("RADIUS accounting request failed\n");
00787 goto error;
00788 }
00789
00790 rc_avpair_free(send);
00791 return 1;
00792
00793 error:
00794 rc_avpair_free(send);
00795 return -1;
00796 }
00797
00798
00799 static void log_reply(struct cell* t , struct sip_msg* reply, unsigned int code, time_t req_time)
00800 {
00801 str* ouri;
00802
00803 if (t->relayed_reply_branch >= 0) {
00804 ouri = &t->uac[t->relayed_reply_branch].uri;
00805 } else {
00806 ouri = GET_NEXT_HOP(t->uas.request);
00807 }
00808
00809 log_request(t->uas.request, ouri, valid_to(t, reply), code, req_time);
00810 }
00811
00812
00813 static void log_ack(struct cell* t , struct sip_msg *ack, time_t req_time)
00814 {
00815 struct sip_msg *rq;
00816 struct hdr_field *to;
00817
00818 rq = t->uas.request;
00819 if (ack->to) to = ack->to;
00820 else to = rq->to;
00821 log_request(ack, GET_RURI(ack), to, t->uas.status, req_time);
00822 }
00823
00824
00825 static void log_missed(struct cell* t, struct sip_msg* reply, unsigned int code, time_t req_time)
00826 {
00827 str* ouri;
00828
00829 if (t->relayed_reply_branch >= 0) {
00830 ouri = &t->uac[t->relayed_reply_branch].uri;
00831 } else {
00832 ouri = GET_NEXT_HOP(t->uas.request);
00833 }
00834
00835 log_request(t->uas.request, ouri , valid_to(t, reply), code, req_time);
00836 }
00837
00838
00839
00840
00841
00842
00843 static int acc_rad_request0(struct sip_msg *rq, char* p1, char* p2)
00844 {
00845 preparse_req(rq);
00846 return log_request(rq, GET_RURI(rq), rq->to, 0, time(0));
00847 }
00848
00849
00850
00851
00852
00853
00854 static int acc_rad_missed0(struct sip_msg *rq, char* p1, char* p2)
00855 {
00856 preparse_req(rq);
00857 return log_request(rq, GET_RURI(rq), rq->to, 0, time(0));
00858 }
00859
00860
00861
00862
00863
00864 static int acc_rad_request1(struct sip_msg *rq, char* p1, char* p2)
00865 {
00866 int code;
00867 preparse_req(rq);
00868 if (get_int_fparam(&code, rq, (fparam_t*)p1) < 0) {
00869 code = 0;
00870 }
00871 return log_request(rq, GET_RURI(rq), rq->to, code, time(0));
00872 }
00873
00874
00875
00876
00877
00878
00879 static int acc_rad_missed1(struct sip_msg *rq, char* p1, char* p2)
00880 {
00881 int code;
00882 preparse_req(rq);
00883 if (get_int_fparam(&code, rq, (fparam_t*)p1) < 0) {
00884 code = 0;
00885 }
00886 return log_request(rq, GET_RURI(rq), rq->to, code, time(0));
00887 }
00888
00889
00890 static void ack_handler(struct cell* t, int type, struct tmcb_params* ps)
00891 {
00892 if (is_acc_on(t->uas.request)) {
00893 preparse_req(ps->req);
00894 log_ack(t, ps->req, (time_t)*(ps->param));
00895 }
00896 }
00897
00898
00899
00900 static void failure_handler(struct cell *t, int type, struct tmcb_params* ps)
00901 {
00902
00903 if (t->uas.request == 0) {
00904 DBG("DBG:acc:failure_handler: No uas.request, skipping local transaction\n");
00905 return;
00906 }
00907
00908 if (is_invite(t) && ps->code >= 300) {
00909 if (is_mc_on(t->uas.request)) {
00910 log_missed(t, ps->rpl, ps->code, (time_t)*(ps->param));
00911 resetflag(t->uas.request, log_missed_flag);
00912 }
00913 }
00914 }
00915
00916
00917
00918 static void replyout_handler(struct cell* t, int type, struct tmcb_params* ps)
00919 {
00920 if (t->uas.request == 0) {
00921 DBG("DBG:acc:replyout_handler: No uas.request, local transaction, skipping\n");
00922 return;
00923 }
00924
00925
00926
00927
00928
00929 failure_handler(t, type, ps);
00930 if (!should_acc_reply(t, ps->code)) return;
00931 if (is_acc_on(t->uas.request)) log_reply(t, ps->rpl, ps->code, (time_t)*(ps->param));
00932 }
00933
00934
00935
00936 static void replyin_handler(struct cell *t, int type, struct tmcb_params* ps)
00937 {
00938
00939 if (t->uas.request == 0) {
00940 LOG(L_ERR, "ERROR:acc:replyin_handler:replyin_handler: 0 request\n");
00941 return;
00942 }
00943
00944
00945
00946 if (((is_invite(t) && ps->code >= 300 && is_mc_on(t->uas.request))
00947 || should_acc_reply(t, ps->code))
00948 && (ps->rpl && ps->rpl != FAKED_REPLY)) {
00949 parse_headers(ps->rpl, HDR_TO_F, 0);
00950 }
00951 }
00952
00953
00954
00955 void on_req(struct cell* t, int type, struct tmcb_params *ps)
00956 {
00957 time_t req_time;
00958
00959 req_time = time(0);
00960
00961 if (is_acc_on(ps->req) || is_mc_on(ps->req)) {
00962 if (tmb.register_tmcb(0, t, TMCB_RESPONSE_OUT, replyout_handler,
00963 (void*)req_time, 0) <= 0) {
00964 LOG(L_ERR, "ERROR:acc:on_req: Error while registering TMCB_RESPONSE_OUT callback\n");
00965 return;
00966 }
00967
00968 if (report_ack) {
00969 if (tmb.register_tmcb(0, t, TMCB_E2EACK_IN, ack_handler,
00970 (void*)req_time, 0) <= 0) {
00971 LOG(L_ERR, "ERROR:acc:on_req: Error while registering TMCB_E2EACK_IN callback\n");
00972 return;
00973 }
00974 }
00975
00976 if (tmb.register_tmcb(0, t, TMCB_ON_FAILURE_RO, failure_handler,
00977 (void*)req_time, 0) <= 0) {
00978 LOG(L_ERR, "ERROR:acc:on_req: Error while registering TMCB_ON_FAILURE_RO callback\n");
00979 return;
00980 }
00981
00982 if (tmb.register_tmcb(0, t, TMCB_RESPONSE_IN, replyin_handler,
00983 (void*)req_time, 0) <= 0) {
00984 LOG(L_ERR, "ERROR:acc:on_req: Error while registering TMCB_RESPONSE_IN callback\n");
00985 return;
00986 }
00987
00988
00989 preparse_req(ps->req);
00990
00991 if (ps->req->REQ_METHOD == METHOD_INVITE) {
00992 DBG("DEBUG: noisy_timer set for accounting\n");
00993 t->flags |= T_NOISY_CTIMER_FLAG;
00994 }
00995 }
00996 }
00997
00998
00999 static int mod_init(void)
01000 {
01001 DICT_VENDOR *vend;
01002 load_tm_f load_tm;
01003
01004
01005 if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) {
01006 LOG(L_ERR, "ERROR:acc:mod_init: can't import load_tm\n");
01007 return -1;
01008 }
01009
01010 if (load_tm( &tmb )==-1) return -1;
01011 if (verify_fmt(log_fmt)==-1) return -1;
01012
01013
01014
01015 if (tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, on_req, 0, 0) <= 0) {
01016 LOG(L_ERR,"ERROR:acc:mod_init: cannot register TMCB_REQUEST_IN "
01017 "callback\n");
01018 return -1;
01019 }
01020
01021 memset(attrs, 0, sizeof(attrs));
01022 memset(vals, 0, sizeof(vals));
01023
01024 attrs[A_USER_NAME].n = "User-Name";
01025 attrs[A_SERVICE_TYPE].n = "Service-Type";
01026 attrs[A_CALLED_STATION_ID].n = "Called-Station-Id";
01027 attrs[A_CALLING_STATION_ID].n = "Calling-Station-Id";
01028 attrs[A_ACCT_STATUS_TYPE].n = "Acct-Status-Type";
01029 attrs[A_ACCT_SESSION_ID].n = "Acct-Session-Id";
01030
01031 attrs[A_SIP_METHOD].n = "Sip-Method";
01032 attrs[A_SIP_RESPONSE_CODE].n = "Sip-Response-Code";
01033 attrs[A_SIP_CSEQ].n = "Sip-CSeq";
01034 attrs[A_SIP_TO_TAG].n = "Sip-To-Tag";
01035 attrs[A_SIP_FROM_TAG].n = "Sip-From-Tag";
01036 attrs[A_SIP_TRANSLATED_REQUEST_ID].n = "Sip-Translated-Request-Id";
01037 attrs[A_SIP_SOURCE_IP_ADDRESS].n = "Sip-Source-IP-Address";
01038 attrs[A_SIP_SOURCE_PORT].n = "Sip-Source-Port";
01039
01040 attrs[A_SER_ATTR].n = "SER-Attr";
01041 attrs[A_SER_FROM].n = "SER-From";
01042 attrs[A_SER_FLAGS].n = "SER-Flags";
01043 attrs[A_SER_ORIGINAL_REQUEST_ID].n = "SER-Original-Request-Id";
01044 attrs[A_SER_TO].n = "SER-To";
01045 attrs[A_SER_DIGEST_USERNAME].n = "SER-Digest-Username";
01046 attrs[A_SER_DIGEST_REALM].n = "SER-Digest-Realm";
01047 attrs[A_SER_REQUEST_TIMESTAMP].n = "SER-Request-Timestamp";
01048 attrs[A_SER_TO_DID].n = "SER-To-DID";
01049 attrs[A_SER_FROM_UID].n = "SER-From-UID";
01050 attrs[A_SER_FROM_DID].n = "SER-From-DID";
01051 attrs[A_SER_TO_UID].n = "SER-To-UID";
01052 attrs[A_SER_RESPONSE_TIMESTAMP].n = "SER-Response-Timestamp";
01053 attrs[A_SER_SERVER_ID].n = "SER-Server-ID";
01054
01055 vals[V_START].n = "Start";
01056 vals[V_STOP].n = "Stop";
01057 vals[V_INTERIM_UPDATE].n = "Interim-Update";
01058 vals[V_FAILED].n = "Failed";
01059 vals[V_SIP_SESSION].n = "Sip-Session";
01060
01061
01062 rc_openlog("ser");
01063
01064 if ((rh = rc_read_config(radius_config)) == NULL) {
01065 LOG(L_ERR, "ERROR:acc:mod_init: Error opening radius config file: %s\n",
01066 radius_config);
01067 return -1;
01068 }
01069
01070 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
01071 LOG(L_ERR, "ERROR:acc:mod_init: Error reading radius dictionary\n");
01072 return -1;
01073 }
01074
01075 vend = rc_dict_findvend(rh, "iptelorg");
01076 if (vend == NULL) {
01077 ERR("RADIUS dictionary is missing required vendor 'iptelorg'\n");
01078 return -1;
01079 }
01080
01081 INIT_AV(rh, attrs, vals, "acc", -1, -1);
01082
01083 if (service_type != -1) {
01084 vals[V_SIP_SESSION].v = service_type;
01085 }
01086
01087 if (parse_attrs(&avps, &avps_n, attrs_param) < 0) {
01088 ERR("Error while parsing 'attrs' module parameter\n");
01089 return -1;
01090 }
01091
01092 return 0;
01093 }