コード例 #1
0
ファイル: cel_radius.c プロジェクト: adaptiman/asterisk
static void radius_log(struct ast_event *event)
{
	int result = ERROR_RC;
	VALUE_PAIR *send = NULL;
	struct ast_cel_event_record record = {
		.version = AST_CEL_EVENT_RECORD_VERSION,
	};

	if (ast_cel_fill_record(event, &record)) {
		return;
	}

	if (build_radius_record(&send, &record)) {
		ast_debug(1, "Unable to create RADIUS record. CEL not recorded!\n");
		goto return_cleanup;
	}

	result = rc_acct(rh, 0, send);
	if (result != OK_RC) {
		ast_log(LOG_ERROR, "Failed to record Radius CEL record!\n");
	}

return_cleanup:
	if (send) {
		rc_avpair_free(send);
	}
}
コード例 #2
0
ファイル: radiusclient.c プロジェクト: ktcunreal/radcli
int
process(void *rh, VALUE_PAIR *send, int acct, int nas_port, int send_info)
{
    VALUE_PAIR *received = NULL;
    char buf[BUF_LEN];
    RC_AAA_CTX *ctx = NULL;
    const unsigned char *p;
    int i, j;

    received = NULL;
    if (acct == 0) {
        i = rc_aaa_ctx(rh, &ctx, nas_port, send, &received, NULL, 1, PW_ACCESS_REQUEST);
        if (received != NULL) {
            printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN));
            rc_avpair_free(received);
        }
        if (ctx) {
            if (send_info) {
                printf("Request-Info-Secret = %s\n", rc_aaa_ctx_get_secret(ctx));
                printf("Request-Info-Vector = ");
                p = rc_aaa_ctx_get_vector(ctx);
                for (j=0; j<AUTH_VECTOR_LEN; j++) {
                    printf("%.2x", (unsigned)p[j]);
                }
                printf("\n");
            }
            rc_aaa_ctx_free(ctx);
        }
    } else {
        i = rc_acct(rh, nas_port, send);
    }

    return (i == OK_RC) ? 0 : 1;
}
コード例 #3
0
ファイル: cel_radius.c プロジェクト: cfhb/vlink-cti
static void *do_monitor(void *data)
{
    int result = ERROR_RC;
    char cdr_full_path[256];
    DIR *cdr_dir;
	VALUE_PAIR *resend = NULL;
	struct dirent *dir_s = NULL;
	int count = 0; // times of resend
	int wait_time = 0;
	
	for(;;){
        sleep(1); /* sleep 1 minute */
		/* Open dir */
		if((cdr_dir=opendir(cdr_directory)) == NULL){
			ast_log(LOG_ERROR,"Failed to open %s\n",cdr_directory);
		} else {
		/* open */
			while((dir_s=readdir(cdr_dir))!=NULL) {
				if(!strcmp(dir_s->d_name,".") || !strcmp(dir_s->d_name,".."))
					continue;
				memset(cdr_full_path,0,sizeof(cdr_full_path));
				snprintf(cdr_full_path,sizeof(cdr_full_path),"%s/%s",cdr_directory,dir_s->d_name);
				resend = get_avp(cdr_full_path);
				if(resend){
					result = rc_acct(rh,0,resend);
				}else{
					ast_log(LOG_ERROR, "get avp return null!");
				}
				if(result != OK_RC){
					ast_log(LOG_ERROR, "Failed to re-record Radius CDR record!\n");
					if(resend){
						ast_avpair_free(resend);
						resend = NULL;
					}
					count++;
					wait_time = count * 60; // reterval to resend cdr record: 60s, 120s,180s,240s......
					ast_log(LOG_DEBUG,"----------wait_time:%d-----------\n", wait_time);
					break;
				}else{
				ast_log(LOG_DEBUG,"----------cdr_full_path:%s send OK!-----------\n", cdr_full_path);
				wait_time = 0;
				count = 0;
				if(remove(cdr_full_path) != 0)
					ast_log(LOG_WARNING,"Failed to delete %s\n",cdr_full_path);
			}
			if(resend){
				ast_avpair_free(resend);
				resend = NULL;
			}
		}
		closedir(cdr_dir);
		}
		
		if (wait_time > 0) {
			ast_log(LOG_DEBUG,"if-wait_time>0----------wait_time:%d-----------\n", wait_time);
			sleep(wait_time);
		}
	}
	return NULL;
}
コード例 #4
0
ファイル: tls-restart.c プロジェクト: ktcunreal/radcli
int process(void *rh, VALUE_PAIR * send, int acct, int nas_port)
{
    VALUE_PAIR *received;
    char msg[PW_MAX_MSG_SIZE];
    char buf[BUF_LEN];
    int i, fd;

    fd = rc_tls_fd(rh);
    if (fd >= 0) {
        dup(fd);
        close(fd);
    }

    received = NULL;
    if (acct == 0) {
        i = rc_auth(rh, nas_port, send, &received, msg);
        if (i != OK_RC) {
            fprintf(stderr, "tls-restart: error sending 1 (ok)\n");
        }

        i = rc_auth(rh, nas_port, send, &received, msg);
        if (i != OK_RC) {
            fprintf(stderr, "tls-restart: error sending 2\n");
            exit(2);
        }
        if (received != NULL) {
            printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN));
            rc_avpair_free(received);
        }
    } else {
        i = rc_acct(rh, nas_port, send);
    }

    return (i == OK_RC) ? 0 : 1;
}
コード例 #5
0
ファイル: mod_xml_radius.c プロジェクト: PauloFer1/FreeSWITCH
switch_status_t mod_xml_radius_accounting_end(switch_core_session_t *session){
	VALUE_PAIR *send = NULL;
	uint32_t service = PW_STATUS_STOP;
	rc_handle *new_handle = NULL;
	switch_xml_t fields = NULL, conditions = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	
	if (GLOBAL_DEBUG ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting accounting stop\n");
		switch_core_session_execute_application(session, "info", NULL);
	}
	
	/* If there are conditions defined, and none of them pass, then skip this accounting */
	if ((conditions = switch_xml_child(globals.acct_start_configs, "conditions")) != NULL &&
		mod_xml_radius_check_conditions(channel, conditions) != SWITCH_STATUS_SUCCESS ) {
		goto end;
	}
	
	if ( mod_xml_radius_new_handle(&new_handle, globals.acct_end_configs) != SWITCH_STATUS_SUCCESS || new_handle == NULL ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new accounting_end handle for call: %s\n",
						  switch_channel_get_variable(channel, "uuid"));
		goto end;		
	}

	if ((fields = switch_xml_child(globals.acct_end_configs, "fields")) == NULL ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n");		
		goto end;
	}
	
	if ( mod_xml_radius_add_params(session, NULL, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n");		
		goto end;
	}
	
	if (rc_avpair_add(new_handle, &send, PW_ACCT_STATUS_TYPE, &service, -1, 0) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
		goto end;
	}	

	if (rc_acct(new_handle, 0, send) == OK_RC) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "mod_xml_radius:  Accounting Stop success\n");
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius:  Accounting Stop failed\n");
	}

 end:
	if ( send ) {
		rc_avpair_free(send);
		send = NULL;
	}
	if ( new_handle) {
		rc_destroy(new_handle);
		new_handle = NULL;
	}
	
	return SWITCH_STATUS_SUCCESS;
}
コード例 #6
0
ファイル: cdr_radius.c プロジェクト: commshare/squeezeterisk
static int radius_log(struct ast_cdr *cdr)
{
	int result = ERROR_RC;
	VALUE_PAIR *send = NULL;

	if (build_radius_record(&send, cdr)) {
		if (option_debug)
			ast_log(LOG_DEBUG, "Unable to create RADIUS record. CDR not recorded!\n");
		return result;
	}
	
	result = rc_acct(rh, 0, send);
	if (result != OK_RC)
		ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");

	return result;
}
コード例 #7
0
int send_acct_func(struct sip_msg* msg, str *s) {

	int i, index = -1;
	VALUE_PAIR *send = NULL;

	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	//LM_DBG("*******************************************\n");

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s->len &&
				!strncmp(sets[i]->set_name.s, s->s, s->len))
				index = i;
	}

	if (index == -1) {
		LM_ERR("set not found\n");
		return -1;
	}

	if (make_send_message(msg, index, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	if (rc_acct(rh, SIP_PORT, send) != OK_RC){
		if (send)
			rc_avpair_free(send);
		LM_ERR("radius accounting message failed to send\n");
		//LM_DBG("*******************************************\n");
		return -1;
	}

	LM_DBG("radius accounting message sent\n");
//	LM_DBG("*******************************************\n");

	return 1;
}
コード例 #8
0
/* 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;
}
コード例 #9
0
ファイル: cdr_radius.c プロジェクト: bugrahantopall/asterisk
static int radius_log(struct ast_cdr *cdr)
{
	int result = ERROR_RC;
	VALUE_PAIR *tosend = NULL;

	if (build_radius_record(&tosend, cdr)) {
		ast_debug(1, "Unable to create RADIUS record. CDR not recorded!\n");
		goto return_cleanup;
	}

	result = rc_acct(rh, 0, tosend);
	if (result != OK_RC) {
		ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");
	}

return_cleanup:
	if (tosend) {
		rc_avpair_free(tosend);
	}

	return result;
}
コード例 #10
0
ファイル: cel_radius.c プロジェクト: cfhb/vlink-cti
static void radius_log(struct ast_event *event)
{
	int result = ERROR_RC;
	VALUE_PAIR *send = NULL;
	int ret = 0;
	char cdr_full_path[256];
	struct ast_cel_event_record record = {
		.version = AST_CEL_EVENT_RECORD_VERSION,
	};

	if (ast_cel_fill_record(event, &record)) {
		return;
	}
	if (build_radius_record(&send, &record)) {
		ast_debug(1, "Unable to create RADIUS record. CEL not recorded!\n");
		goto return_cleanup;
	}

	result = rc_acct(rh, 0, send);
	if (result != OK_RC) {
		ast_log(LOG_ERROR, "Failed to record Radius CEL record! unique_id=%s\n", record.unique_id);
        	/* file name */
        	if(record.unique_id && (!ast_strlen_zero(record.unique_id))){
            		snprintf(cdr_full_path,sizeof(cdr_full_path),"%s/%s",cdr_dir_tmp,record.unique_id);
			/* write cdr to file if rc_acct failed */
			ret = save_avp_to_file(cdr_full_path,record.unique_id,send);
			if(!ret){
				ast_log(LOG_ERROR,"Failed to write cdr to file! unique_id=%s\n", record.unique_id);
			}
        	}
		goto return_cleanup;
	}

return_cleanup:
	if (send) {
		rc_avpair_free(send);
	}
}
コード例 #11
0
ファイル: radius.c プロジェクト: intersvyaz/zerod
/**
 * @param[in] session Session
 * @param[in] status Accounting status (PW_STATUS_START, PW_STATUS_STOP, PW_STATUS_ALIVE)
 * @param[in] cause Accounting termination cause (used only in case of PW_STATUS_STOP)
 * @param[in] req Accounting request data.
 */
static zrad_status_t zrad_acct_request(rc_handle *radh, const zrad_acct_req_t *req)
{
    zrad_status_t ret;
    VALUE_PAIR *request_attrs = NULL;

    int success = rc_avpair_add(radh, &request_attrs, PW_CALLING_STATION_ID, req->calling_station_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_AUTHENTIC, &req->authentic, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_FRAMED_IP_ADDRESS, &req->framed_ip_addr, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_USER_NAME, req->username, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_SESSION_ID, req->session_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_NAS_IDENTIFIER, req->nas_id, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_OCTETS, &req->octets_down, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_PACKETS, &req->packets_down, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_OCTETS, &req->octets_up, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_PACKETS, &req->packets_down, -1, 0)
                  && (!req->gigawords_down ||
                      rc_avpair_add(radh, &request_attrs, PW_ACCT_OUTPUT_GIGAWORDS, &req->gigawords_up, -1, 0))
                  && (!req->gigawords_down ||
                      rc_avpair_add(radh, &request_attrs, PW_ACCT_INPUT_GIGAWORDS, &req->gigawords_down, -1, 0))
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_STATUS_TYPE, &req->status, -1, 0);

    if (success && PW_STATUS_STOP == req->status) {
        success = success
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_SESSION_TIME, &req->session_time, -1, 0)
                  && rc_avpair_add(radh, &request_attrs, PW_ACCT_TERMINATE_CAUSE, &req->term_cause, -1, 0);
    }

    if (likely(success)) {
        ret = (zrad_status_t) rc_acct(radh, 0, request_attrs);
    } else {
        ret = ZRAD_OTHER;
    }

    if (likely(request_attrs)) rc_avpair_free(request_attrs);

    return ret;
}
コード例 #12
0
ファイル: acc_radius_mod.c プロジェクト: 4N7HR4X/kamailio
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;
}
コード例 #13
0
ファイル: rad.c プロジェクト: KISSMonX/opensips
/*
	Radius implementation for the send_message callback
 */
int rad_send_message(aaa_conn* rh, aaa_message* request, aaa_message** reply) {
	char msg[4096];
	VALUE_PAIR *vp;
 	DICT_ATTR *attr;
	int result;

	if (!rh) {
		LM_ERR("invalid aaa connection argument\n");
		return -1;
	}

	if (!request) {
		LM_ERR("invalid argument\n");
		return -1;
	}

	if (request->type == AAA_AUTH) {

		*reply = (aaa_message*) pkg_malloc (sizeof(aaa_message));

		if (!(*reply)) {
			LM_ERR("no pkg memory left \n");
			return -1;
		}

		(*reply)->type = AAA_RECV;
		(*reply)->avpair = NULL;
		(*reply)->last_found = NULL;

		result = rc_auth(rh, SIP_PORT, (VALUE_PAIR*) request->avpair,
						(VALUE_PAIR**)(void*)&(*reply)->avpair, msg);

		if (result == OK_RC) {
			attr = rc_dict_findattr(rh, "SIP-AVP");
			if (attr) {
				vp = (*reply)->avpair;
				for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
					if (extract_avp(vp)) {
						LM_ERR("extract_avp failed\n");
						return -1;
					}
				return 0;
			} else {
				LM_ERR("SIP-AVP was not found in the radius dictionary\n");
				return -1;
			}
		} else if (result == REJECT_RC) {
			LM_DBG("rc_auth function succeded with result REJECT_RC\n");
			return result;
		} else {
			LM_ERR("rc_auth function failed\n");
			return -1;
		}
	}

	if (request->type == AAA_ACCT) {
			return rc_acct(rh, SIP_PORT, (VALUE_PAIR*) request->avpair);
	}

	LM_ERR("send message failure\n");
	return -1;
}
コード例 #14
0
ファイル: acc_radius_mod.c プロジェクト: Jared-Prime/kamailio
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;
}
コード例 #15
0
int
main (int argc, char **argv)
{
	int			result = ERROR_RC;
	VALUE_PAIR	*send = NULL;
   	UINT4		client_port;
   	int			c;
	VALUE_PAIR	*vp;
	DICT_VALUE  *dval;
	char *username, *service, *fproto, *type;
	char *path_radiusclient_conf = RC_CONFIG_FILE;
	char *ttyn = NULL;
	rc_handle *rh;

	extern char *optarg;

	pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0];

	rc_openlog(pname);

	while ((c = getopt(argc,argv,"f:i:hV")) > 0)
	{
		switch(c)
		{
			case 'f':
				path_radiusclient_conf = optarg;
				break;
			case 'i':
				ttyn = optarg;
				break;
			case 'V':
				version();
				break;
			case 'h':
				usage();
				break;
			default:
				exit(ERROR_RC);
				break;
		}
	}

	if ((rh = rc_read_config(path_radiusclient_conf)) == NULL)
		exit(ERROR_RC);

	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
		exit (ERROR_RC);

	if (rc_read_mapfile(rh, rc_conf_str(rh, "mapfile")) != 0)
		exit (ERROR_RC);

	if (ttyn != NULL)
	{
		client_port = rc_map2id(rh, ttyn);
	}
	else
	{
		/* we take stdout here, because stdin is usually connected
	 	 *  to our input file
	 	 */
	 	if ((ttyn = ttyname(1)) != NULL)
	 	{
			client_port = rc_map2id(rh, ttyn);
		}
		else
		{
			client_port = 0;
		}
	}

	if ((send = rc_avpair_readin(rh, stdin))) {

		username = service = type = "(unknown)";
		fproto = NULL;

		if ((vp = rc_avpair_get(send, PW_ACCT_STATUS_TYPE, 0)) != NULL)
				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
					type = dval->name;
				}

		if ((vp = rc_avpair_get(send, PW_USER_NAME, 0)) != NULL)
				username = vp->strvalue;

		if ((vp = rc_avpair_get(send, PW_SERVICE_TYPE, 0)) != NULL)
				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
					service = dval->name;
				}

		if (vp && (vp->lvalue == PW_FRAMED) &&
			((vp = rc_avpair_get(send, PW_FRAMED_PROTOCOL, 0)) != NULL))
				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
					fproto = dval->name;
				}

		result = rc_acct(rh, client_port, send);
		if (result == OK_RC)
		{
			fprintf(stderr, SC_ACCT_OK);
			rc_log(LOG_NOTICE, "accounting OK, type %s, username %s, service %s%s%s",
				   type, username, service,(fproto)?"/":"", (fproto)?fproto:"");
		}
		else
		{
			fprintf(stderr, SC_ACCT_FAILED, result);
			rc_log(LOG_NOTICE, "accounting FAILED, type %s, username %s, service %s%s%s",
				   type, username, service,(fproto)?"/":"", (fproto)?fproto:"");
		}
		rc_avpair_free(send);
	}

	exit (result);
}
コード例 #16
0
ファイル: mod_radius_cdr.c プロジェクト: AricGod/FreeSWITCH
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	switch_xml_t cdr = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	rc_handle *rad_config;
	switch_status_t retval = SWITCH_STATUS_TERM;
	VALUE_PAIR *send = NULL;
	uint32_t client_port = 0;
	uint32_t framed_addr = 0;
	uint32_t status_type = PW_STATUS_STOP;
	switch_time_t callstartdate = 0;
	switch_time_t callanswerdate = 0;
	switch_time_t callenddate = 0;
	switch_time_t calltransferdate = 0;
	switch_time_t billusec = 0;
	uint32_t billsec = 0;
	char *uuid_str;

	switch_time_exp_t tm;
	char buffer[32] = "";

	if (globals.shutdown) {
		return SWITCH_STATUS_FALSE;
	}


	if (channel) {
		const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_stop");
		if (switch_true(disable_flag)) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Stop\n");
			return SWITCH_STATUS_SUCCESS;
		}
	}

	switch_thread_rwlock_rdlock(globals.rwlock);

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_reporting\n");

	rad_config = my_radius_init();

	if (rad_config == NULL) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, session not logged.\n");
		goto end;
	}

	if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
		uuid_str = switch_core_session_get_uuid(session);
	} else {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n");
		goto end;
	}

	/* Create the radius packet */

	/* Set Status Type */
	if (rc_avpair_add(rad_config, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str);
		rc_destroy(rad_config);
		goto end;
	}

	if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_ID, uuid_str, -1, 0) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str);
		rc_destroy(rad_config);
		goto end;
	}

	/* Add VSAs */

	if (channel) {
		switch_call_cause_t cause;
		switch_caller_profile_t *profile;

		cause = switch_channel_get_cause(channel);
		if (rc_avpair_add(rad_config, &send, PW_FS_HANGUPCAUSE, &cause, -1, PW_FS_PEC) == NULL) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause);
			rc_destroy(rad_config);
			goto end;
		}

		profile = switch_channel_get_caller_profile(channel);

		if (profile) {

			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Calculating billable time\n");

			/* calculate billable time */
			callstartdate = profile->times->created;
			callanswerdate = profile->times->answered;
			calltransferdate = profile->times->transferred;
			callenddate = profile->times->hungup;

			if (switch_channel_test_flag(channel, CF_ANSWERED)) {
				if (callstartdate && callanswerdate) {
					if (callenddate)
						billusec = callenddate - callanswerdate;
					else if (calltransferdate)
						billusec = calltransferdate - callanswerdate;
				}
			} else if (switch_channel_test_flag(channel, CF_TRANSFER)) {
				if (callanswerdate && calltransferdate)
					billusec = calltransferdate - callanswerdate;
			}
			billsec = (billusec / 1000000);

			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Finished calculating billable time\n");

			if (profile->username) {
				if (rc_avpair_add(rad_config, &send, PW_USER_NAME, (void *) profile->username, -1, 0) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->caller_id_number) {
				if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->caller_id_name) {
				if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->destination_number) {
				if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->dialplan) {
				if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->network_addr) {
				inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr);
				framed_addr = htonl(framed_addr);
				if (rc_avpair_add(rad_config, &send, PW_FRAMED_IP_ADDRESS, &framed_addr, -1, 0) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->rdnis) {
				if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->context) {
				if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->ani) {
				if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->aniii) {
				if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->source) {
				if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) {
				if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP,
								  (void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source);
					rc_destroy(rad_config);
					goto end;
				}
			}
			if (rc_avpair_add(rad_config, &send, PW_FS_BILLUSEC, &billusec, -1, PW_FS_PEC) == NULL) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Billusec: %u\n", (uint32_t) billusec);
				rc_destroy(rad_config);
				goto end;
			}

			if (callstartdate > 0) {
				switch_time_exp_lt(&tm, callstartdate);
				switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
								tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
								tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
				if (rc_avpair_add(rad_config, &send, PW_FS_CALLSTARTDATE, &buffer, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer);
					rc_destroy(rad_config);
					goto end;
				}
			}

			if (callanswerdate > 0) {
				switch_time_exp_lt(&tm, callanswerdate);
				switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
								tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
								tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
				if (rc_avpair_add(rad_config, &send, PW_FS_CALLANSWERDATE, &buffer, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer);
					rc_destroy(rad_config);
					goto end;
				}
			}

			if (calltransferdate > 0) {
				switch_time_exp_lt(&tm, calltransferdate);
				switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
								tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
								tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
				if (rc_avpair_add(rad_config, &send, PW_FS_CALLTRANSFERDATE, &buffer, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer);
					rc_destroy(rad_config);
					goto end;
				}
			}

			if (callenddate > 0) {
				switch_time_exp_lt(&tm, callenddate);
				switch_snprintf(buffer, sizeof(buffer), "%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d",
								tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
								tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600);
				if (rc_avpair_add(rad_config, &send, PW_FS_CALLENDDATE, &buffer, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer);
					rc_destroy(rad_config);
					goto end;
				}
			}

			if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_TIME, &billsec, -1, 0) == NULL) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-Time: %u\n", billsec);
				rc_destroy(rad_config);
				goto end;
			}
			
			{
				const char *direction_str = profile->direction == SWITCH_CALL_DIRECTION_INBOUND ? "inbound" : "outbound";
				
				if (rc_avpair_add(rad_config, &send, PW_FS_DIRECTION, (void *) direction_str, -1, PW_FS_PEC) == NULL) {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Direction: %s\n", direction_str);
					rc_destroy(rad_config);
					goto end;
				}
			}
			
		} else {				/* no profile, can't create data to send */
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "profile == NULL\n");
		}
	}

	if (rc_acct(rad_config, client_port, send) == OK_RC) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RADIUS Accounting OK\n");
		retval = SWITCH_STATUS_SUCCESS;
	} else {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RADIUS Accounting Failed\n");
		retval = SWITCH_STATUS_TERM;
	}
	rc_avpair_free(send);
	rc_destroy(rad_config);

  end:
	switch_xml_free(cdr);
	switch_thread_rwlock_unlock(globals.rwlock);
	return (retval);
}
コード例 #17
0
ファイル: acc.c プロジェクト: AlessioCasco/kamailio
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;
}
コード例 #18
0
ファイル: overlord.c プロジェクト: carriercomm/zerod
/**
 * Send radius accounting packet.
 * @param[in] sess Session
 * @param[in] status Accounting status (PW_STATUS_START, PW_STATUS_STOP, PW_STATUS_ALIVE)
 * @param[in] cause Accounting termination cause (used only in case of PW_STATUS_STOP)
 * @return Zero on success (one of *_RC codes).
 */
static int session_accounting(struct zsession *sess, uint32_t status, uint32_t term_cause)
{
    int ret = OTHER_RC;
    VALUE_PAIR *request_attrs = NULL;
    rc_handle *rh = zinst()->radh;
    struct in_addr ip_addr;
    char ip_str[INET_ADDRSTRLEN];

    uint64_t traff_down = atomic_load_explicit(&sess->traff_down, memory_order_acquire);
    uint64_t traff_up = atomic_load_explicit(&sess->traff_up, memory_order_acquire);
    uint32_t octets_down = (uint32_t) (traff_down % UINT32_MAX);
    uint32_t octets_up = (uint32_t) (traff_up % UINT32_MAX);
    uint32_t packets_down = atomic_load_explicit(&sess->packets_down, memory_order_acquire) % UINT32_MAX;
    uint32_t packets_up = atomic_load_explicit(&sess->packets_up, memory_order_acquire) % UINT32_MAX;
    uint32_t gigawords_down = 0;
    uint32_t gigawords_up = 0;

    char session_id[255];
    snprintf(session_id, sizeof(session_id), "%s-%" PRIu32, sess->client->login, sess->ip);

    ip_addr.s_addr = htonl(sess->ip);
    if (unlikely(NULL == inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str)))) {
        goto end;
    }

    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_CALLING_STATION_ID, ip_str, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_FRAMED_IP_ADDRESS, &sess->ip, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_USER_NAME, sess->client->login, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_SESSION_ID, session_id, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_NAS_IDENTIFIER, zcfg()->radius_nas_identifier, -1, 0))) {
        goto end;
    }
    if (PW_STATUS_STOP == status) {
        if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_TERMINATE_CAUSE, &term_cause, -1, 0))) {
            goto end;
        }
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_STATUS_TYPE, &status, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_OCTETS, &octets_down, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_PACKETS, &packets_down, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_OCTETS, &octets_up, -1, 0))) {
        goto end;
    }
    if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_PACKETS, &packets_down, -1, 0))) {
        goto end;
    }
    if (unlikely(UINT32_MAX < traff_down)) {
        gigawords_down = (uint32_t) (traff_down / UINT32_MAX);
        if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_INPUT_GIGAWORDS, &gigawords_down, -1, 0))) {
            goto end;
        }
    }
    if (unlikely(UINT32_MAX < traff_up)) {
        gigawords_up = (uint32_t) (traff_up / UINT32_MAX);
        if (unlikely(NULL == rc_avpair_add(rh, &request_attrs, PW_ACCT_OUTPUT_GIGAWORDS, &gigawords_up, -1, 0))) {
            goto end;
        }
    }

    ret = rc_acct(rh, 0, request_attrs);
    if (unlikely(OK_RC != ret)) {
        ZERO_LOG(LOG_ERR, "radius accounting failed %s (code:%d)", ip_str, ret);
        goto end;
    }

    atomic_fetch_sub_explicit(&sess->traff_down, traff_down, memory_order_release);
    atomic_fetch_sub_explicit(&sess->traff_up, traff_up, memory_order_release);
    atomic_fetch_sub_explicit(&sess->packets_down, packets_down, memory_order_release);
    atomic_fetch_sub_explicit(&sess->packets_up, packets_up, memory_order_release);

    end:
    if (request_attrs) {
        rc_avpair_free(request_attrs);
    }

    return ret;
}
コード例 #19
0
ファイル: acc.c プロジェクト: OPSF/uClinux
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;
}