📄 radius.c
字号:
rstate.class, rstate.class_len, VENDOR_NONE); av_type = PW_STATUS_START; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); if (*remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); av_type = PW_RADIUS; rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) ); rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); hisaddr = ho->hisaddr; av_type = htonl(hisaddr); rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.acctserver) { result = rc_acct_using_server(rstate.acctserver, rstate.client_port, send); } else { result = rc_acct(rstate.client_port, send); } rc_avpair_free(send); if (result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Accounting START failed for %s", rstate.user); } else { rstate.accounting_started = 1; /* Kick off periodic accounting reports */ if (rstate.acct_interim_interval) { TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval); } }}/*********************************************************************** %FUNCTION: radius_acct_stop* %ARGUMENTS:* None* %RETURNS:* Nothing* %DESCRIPTION:* Sends a "stop" accounting message to the RADIUS server.***********************************************************************/static voidradius_acct_stop(void){ UINT4 av_type; VALUE_PAIR *send = NULL; ipcp_options *ho = &ipcp_hisoptions[0]; u_int32_t hisaddr; int result; if (!rstate.initialized) { return; } if (!rstate.accounting_started) { return; } rstate.accounting_started = 0; rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); av_type = PW_STATUS_STOP; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); av_type = PW_RADIUS; rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); if (link_stats_valid) { av_type = link_connect_time; rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); av_type = link_stats.bytes_out; rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); av_type = link_stats.bytes_in; rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); av_type = link_stats.pkts_out; rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); av_type = link_stats.pkts_in; rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE); } if (*remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) ); rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_NAS_ERROR; switch( status ) { case EXIT_OK: case EXIT_USER_REQUEST: av_type = PW_USER_REQUEST; break; case EXIT_HANGUP: case EXIT_PEER_DEAD: case EXIT_CONNECT_FAILED: av_type = PW_LOST_CARRIER; break; case EXIT_INIT_FAILED: case EXIT_OPEN_FAILED: case EXIT_LOCK_FAILED: case EXIT_PTYCMD_FAILED: av_type = PW_PORT_ERROR; break; case EXIT_PEER_AUTH_FAILED: case EXIT_AUTH_TOPEER_FAILED: case EXIT_NEGOTIATION_FAILED: case EXIT_CNID_AUTH_FAILED: av_type = PW_SERVICE_UNAVAILABLE; break; case EXIT_IDLE_TIMEOUT: av_type = PW_ACCT_IDLE_TIMEOUT; break; case EXIT_CONNECT_TIME: av_type = PW_ACCT_SESSION_TIMEOUT; break; #ifdef MAXOCTETS case EXIT_TRAFFIC_LIMIT: av_type = PW_NAS_REQUEST; break;#endif default: av_type = PW_NAS_ERROR; break; } rc_avpair_add(&send, PW_ACCT_TERMINATE_CAUSE, &av_type, 0, VENDOR_NONE); hisaddr = ho->hisaddr; av_type = htonl(hisaddr); rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.acctserver) { result = rc_acct_using_server(rstate.acctserver, rstate.client_port, send); } else { result = rc_acct(rstate.client_port, send); } if (result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Accounting STOP failed for %s", rstate.user); } rc_avpair_free(send);}/*********************************************************************** %FUNCTION: radius_acct_interim* %ARGUMENTS:* None* %RETURNS:* Nothing* %DESCRIPTION:* Sends an interim accounting message to the RADIUS server***********************************************************************/static voidradius_acct_interim(void *ignored){ UINT4 av_type; VALUE_PAIR *send = NULL; ipcp_options *ho = &ipcp_hisoptions[0]; u_int32_t hisaddr; int result; if (!rstate.initialized) { return; } if (!rstate.accounting_started) { return; } rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); av_type = PW_STATUS_ALIVE; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); av_type = PW_RADIUS; rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); /* Update link stats */ update_link_stats(0); if (link_stats_valid) { link_stats_valid = 0; /* Force later code to update */ av_type = link_connect_time; rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); av_type = link_stats.bytes_out; rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); av_type = link_stats.bytes_in; rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); av_type = link_stats.pkts_out; rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); av_type = link_stats.pkts_in; rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE); } if (*remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) ); rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); hisaddr = ho->hisaddr; av_type = htonl(hisaddr); rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.acctserver) { result = rc_acct_using_server(rstate.acctserver, rstate.client_port, send); } else { result = rc_acct(rstate.client_port, send); } if (result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Interim accounting failed for %s", rstate.user); } rc_avpair_free(send); /* Schedule another one */ TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);}/*********************************************************************** %FUNCTION: radius_ip_up* %ARGUMENTS:* opaque -- ignored* arg -- ignored* %RETURNS:* Nothing* %DESCRIPTION:* Called when IPCP is up. We'll do a start-accounting record.***********************************************************************/static voidradius_ip_up(void *opaque, int arg){ radius_acct_start();}/*********************************************************************** %FUNCTION: radius_ip_down* %ARGUMENTS:* opaque -- ignored* arg -- ignored* %RETURNS:* Nothing* %DESCRIPTION:* Called when IPCP is down. We'll do a stop-accounting record.***********************************************************************/static voidradius_ip_down(void *opaque, int arg){ radius_acct_stop();}/*********************************************************************** %FUNCTION: radius_init* %ARGUMENTS:* msg -- buffer of size BUF_LEN for error message* %RETURNS:* negative on failure; non-negative on success* %DESCRIPTION:* Initializes radiusclient library***********************************************************************/static intradius_init(char *msg){ if (rstate.initialized) { return 0; } if (config_file && *config_file) { strlcpy(rstate.config_file, config_file, MAXPATHLEN-1); } rstate.initialized = 1; if (rc_read_config(rstate.config_file) != 0) { slprintf(msg, BUF_LEN, "RADIUS: Can't read config file %s", rstate.config_file); return -1; } if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) { slprintf(msg, BUF_LEN, "RADIUS: Can't read dictionary file %s", rc_conf_str("dictionary")); return -1; } if (rc_read_mapfile(rc_conf_str("mapfile")) != 0) { slprintf(msg, BUF_LEN, "RADIUS: Can't read map file %s", rc_conf_str("mapfile")); return -1; } /* Add av pairs saved during option parsing */ while (avpopt) { struct avpopt *n = avpopt->next; rc_avpair_parse(avpopt->vpstr, &rstate.avp); free(avpopt->vpstr); free(avpopt); avpopt = n; } return 0;}/*********************************************************************** %FUNCTION: get_client_port* %ARGUMENTS:* ifname -- PPP interface name (e.g. "ppp7")* %RETURNS:* The NAS port number (e.g. 7)* %DESCRIPTION:* Extracts the port number from the interface name***********************************************************************/static intget_client_port(char *ifname){ int port; if (sscanf(ifname, "ppp%d", &port) == 1) { return port; } return rc_map2id(ifname);}/*********************************************************************** %FUNCTION: radius_allowed_address* %ARGUMENTS:* addr -- IP address* %RETURNS:* 1 if we're allowed to use that IP address; 0 if not; -1 if we do* not know.***********************************************************************/static intradius_allowed_address(u_int32_t addr){ ipcp_options *wo = &ipcp_wantoptions[0]; if (!rstate.choose_ip) { /* If RADIUS server said any address is OK, then fine... */ if (rstate.any_ip_addr_ok) { return 1; } /* Sigh... if an address was supplied for remote host in pppd options, it has to match that. */ if (wo->hisaddr != 0 && wo->hisaddr == addr) { return 1; } return 0; } if (addr == rstate.ip_addr) return 1; return 0;}/* Useful for other plugins */char *radius_logged_in_user(void){ return rstate.user;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -