/* skip leading text and begin with first item's * separator ", " which will be overwritten by the * leading text later * */ static int log_request(struct sip_msg* rq, str* ouri, struct hdr_field* to, unsigned int code, time_t req_time) { VALUE_PAIR *send; UINT4 av_type; send = NULL; if (skip_cancel(rq)) return 1; if (fmt2rad(log_fmt, rq, ouri, to, code, &send, req_time) < 0) goto error; /* Add Acct-Status-Type attribute */ av_type = rad_status(rq, code); if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_ACCT_STATUS_TYPE].v), &av_type, -1, VENDOR(attrs[A_ACCT_STATUS_TYPE].v))) { ERR("Add Status-Type\n"); goto error; } /* Add Service-Type attribute */ av_type = (service_type != -1) ? service_type : vals[V_SIP_SESSION].v; if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SERVICE_TYPE].v), &av_type, -1, VENDOR(attrs[A_SERVICE_TYPE].v))) { ERR("add STATUS_TYPE\n"); goto error; } /* Add User-Name attribute */ if (add_user_name(rq, rh, &send) < 0) goto error; /* Send the request out */ if (rc_acct(rh, SIP_PORT, send) != OK_RC) { ERR("RADIUS accounting request failed\n"); goto error; } rc_avpair_free(send); return 1; error: rc_avpair_free(send); return -1; }
int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf) { int attr_cnt; VALUE_PAIR *send; uint32_t av_type; int offset; int i; int m=0; int o=0; int rc_result=-1; double tsecmicro; char smicrosec[18]; send=NULL; attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr ); /* not interested in the last 2 values */ attr_cnt -= 2; av_type = rad_status( req, inf->env->code); /* RADIUS status */ ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1); av_type = rd_vals[RV_SIP_SESSION].v; /* session*/ ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1); av_type = (uint32_t)inf->env->code; /* status=integer */ ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1); av_type = req->REQ_METHOD; /* method */ ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1); // Event Time Stamp with Microseconds if(rad_time_mode==1){ gettimeofday(&inf->env->tv, NULL); tsecmicro=inf->env->tv.tv_sec+((double)inf->env->tv.tv_usec/1000000.0); //radius client doesn t support double so convert it sprintf(smicrosec,"%17.6f",tsecmicro); ADD_RAD_AVPAIR(RA_TIME_STAMP, &smicrosec, -1); }else{ av_type = (uint32_t)inf->env->ts; ADD_RAD_AVPAIR(RA_TIME_STAMP, &av_type, -1); } /* add extra also */ o = accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt, inf->iarr+attr_cnt, inf->tarr+attr_cnt); attr_cnt += o; m = attr_cnt; /* add the values for the vector - start from 1 instead of * 0 to skip the first value which is the METHOD as string */ offset = RA_STATIC_MAX-1; for( i=1; i<attr_cnt; i++) { switch (inf->tarr[i]) { case TYPE_STR: ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len); break; case TYPE_INT: ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1); break; default: break; } } /* call-legs attributes also get inserted */ if ( inf->leg_info ) { offset += attr_cnt; attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1); do { for (i=0; i<attr_cnt; i++) ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len ); }while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr, inf->tarr, 0))!=0 ); } rc_result=rc_acct(rh, SIP_PORT, send); if (rc_result==ERROR_RC) { LM_ERR("Radius accounting - ERROR - \n"); goto error; }else if(rc_result==BADRESP_RC){ LM_ERR("Radius accounting - BAD RESPONSE \n"); goto error; }else if(rc_result==TIMEOUT_RC){ LM_ERR("Radius accounting - TIMEOUT \n"); goto error; }else if(rc_result==REJECT_RC){ LM_ERR("Radius accounting - REJECTED \n"); goto error; }else if(rc_result==OK_RC){ LM_DBG("Radius accounting - OK \n"); }else{ LM_ERR("Radius accounting - Unknown response \n"); goto error; } rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m); return 1; error: rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m); return -1; }
int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf) { int attr_cnt; VALUE_PAIR *send; uint32_t av_type; int offset; int i; send=NULL; attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr ); /* not interested in the last 2 values */ attr_cnt -= 2; av_type = rad_status( req, inf->env->code); /* RADIUS status */ ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1); av_type = rd_vals[RV_SIP_SESSION].v; /* session*/ ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1); av_type = (uint32_t)inf->env->code; /* status=integer */ ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1); av_type = req->REQ_METHOD; /* method */ ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1); /* unix time */ av_type = (uint32_t)inf->env->ts; ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1); /* add extra also */ attr_cnt += accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt, inf->iarr+attr_cnt, inf->tarr+attr_cnt); /* add the values for the vector - start from 1 instead of * 0 to skip the first value which is the METHOD as string */ offset = RA_STATIC_MAX-1; for( i=1; i<attr_cnt; i++) { switch (inf->tarr[i]) { case TYPE_STR: ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len); break; case TYPE_INT: ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1); break; default: break; } } /* call-legs attributes also get inserted */ if ( inf->leg_info ) { offset += attr_cnt; attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1); do { for (i=0; i<attr_cnt; i++) ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len ); }while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr, inf->tarr, 0))!=0 ); } if (rc_acct(rh, SIP_PORT, send)!=OK_RC) { LM_ERR("radius-ing failed\n"); goto error; } rc_avpair_free(send); return 1; error: rc_avpair_free(send); return -1; }
int acc_rad_request( struct sip_msg *rq, struct hdr_field *to, str *phrase ) { str* val_arr[ALL_LOG_FMT_LEN+1]; str atr_arr[ALL_LOG_FMT_LEN+1]; int attr_cnt; VALUE_PAIR *send; UINT4 av_type; int i; int dummy_len; str* user; str* realm; str user_name; struct sip_uri puri; struct to_body* from; #ifdef _OBSO char nullcode="00000"; char ccode[6]; char *c; #endif send=NULL; if (skip_cancel(rq)) return 1; attr_cnt=fmt2strar( RAD_ACC_FMT, rq, to, phrase, &dummy_len, &dummy_len, val_arr, atr_arr); if (attr_cnt!=(sizeof(RAD_ACC_FMT)-1)) { LOG(L_ERR, "ERROR: acc_rad_request: fmt2strar failed\n"); goto error; } av_type=rad_status(rq, phrase); if (!rc_avpair_add(rh, &send, attrs[A_ACCT_STATUS_TYPE].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add STATUS_TYPE\n"); goto error; } av_type=vals[V_SIP_SESSION].v; if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add STATUS_TYPE\n"); goto error; } av_type=phrase2code(phrase); /* status=integer */ /* if (phrase.len<3) c=nullcode; else { memcpy(ccode, phrase.s, 3); ccode[3]=0;c=nullcode;} */ if (!rc_avpair_add(rh, &send, attrs[A_SIP_RESPONSE_CODE].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add RESPONSE_CODE\n"); goto error; } av_type=rq->REQ_METHOD; if (!rc_avpair_add(rh, &send, attrs[A_SIP_METHOD].v, &av_type, -1, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: add SIP_METHOD\n"); goto error; } /* Handle User-Name as a special case */ user=cred_user(rq); /* try to take it from credentials */ if (user) { realm = cred_realm(rq); if (realm) { user_name.len = user->len+1+realm->len; user_name.s = pkg_malloc(user_name.len); if (!user_name.s) { LOG(L_ERR, "ERROR: acc_rad_request: no memory\n"); goto error; } memcpy(user_name.s, user->s, user->len); user_name.s[user->len] = '@'; memcpy(user_name.s+user->len+1, realm->s, realm->len); if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); pkg_free(user_name.s); goto error; } pkg_free(user_name.s); } else { user_name.len = user->len; user_name.s = user->s; if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); goto error; } } } else { /* from from uri */ if (rq->from && (from=get_from(rq)) && from->uri.len) { if (parse_uri(from->uri.s, from->uri.len, &puri) < 0 ) { LOG(L_ERR, "ERROR: acc_rad_request: Bad From URI\n"); goto error; } user_name.len = puri.user.len+1+puri.host.len; user_name.s = pkg_malloc(user_name.len); if (!user_name.s) { LOG(L_ERR, "ERROR: acc_rad_request: no memory\n"); goto error; } memcpy(user_name.s, puri.user.s, puri.user.len); user_name.s[puri.user.len] = '@'; memcpy(user_name.s+puri.user.len+1, puri.host.s, puri.host.len); if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); pkg_free(user_name.s); goto error; } pkg_free(user_name.s); } else { user_name.len = na.len; user_name.s = na.s; if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %d\n", attrs[A_USER_NAME].v ); goto error; } } } /* Remaining attributes from rad_attr vector */ for(i=0; i<attr_cnt; i++) { if (!rc_avpair_add(rh, &send, attrs[rad_attr[i]].v, val_arr[i]->s,val_arr[i]->len, 0)) { LOG(L_ERR, "ERROR: acc_rad_request: rc_avpaid_add " "failed for %s\n", attrs[rad_attr[i]].n ); goto error; } } if (rc_acct(rh, SIP_PORT, send)!=OK_RC) { LOG(L_ERR, "ERROR: acc_rad_request: radius-ing failed\n"); goto error; } rc_avpair_free(send); return 1; error: rc_avpair_free(send); return -1; }
int acc_rad_request( struct sip_msg *req ) { int attr_cnt; VALUE_PAIR *send; UINT4 av_type; int offset; int i; int m; int o; send=NULL; attr_cnt = core2strar( req, val_arr, int_arr, type_arr ); /* not interested in the last 2 values */ attr_cnt -= 2; av_type = rad_status( req, acc_env.code); /* RADIUS status */ ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1); av_type = rd_vals[RV_SIP_SESSION].v; /* session*/ ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1); av_type = (UINT4)acc_env.code; /* status=integer */ ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1); av_type = req->REQ_METHOD; /* method */ ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1); /* unix time */ av_type = (UINT4)acc_env.ts; ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1); /* add extra also */ o = extra2strar(rad_extra, req, val_arr+attr_cnt, int_arr+attr_cnt, type_arr+attr_cnt); attr_cnt += o; m = attr_cnt; /* add the values for the vector - start from 1 instead of * 0 to skip the first value which is the METHOD as string */ offset = RA_STATIC_MAX-1; for( i=1; i<attr_cnt; i++) { switch (type_arr[i]) { case TYPE_STR: ADD_RAD_AVPAIR(offset+i, val_arr[i].s, val_arr[i].len); break; case TYPE_INT: ADD_RAD_AVPAIR(offset+i, &(int_arr[i]), -1); break; default: break; } } /* call-legs attributes also get inserted */ if ( leg_info ) { offset += attr_cnt; attr_cnt = legs2strar(leg_info,req,val_arr,int_arr,type_arr,1); do { for (i=0; i<attr_cnt; i++) ADD_RAD_AVPAIR( offset+i, val_arr[i].s, val_arr[i].len ); }while ( (attr_cnt=legs2strar(leg_info,req,val_arr,int_arr, type_arr, 0))!=0 ); } if (rc_acct(rh, SIP_PORT, send)!=OK_RC) { LM_ERR("radius-ing failed\n"); goto error; } rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); return 1; error: rc_avpair_free(send); /* free memory allocated by extra2strar */ free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); return -1; }