📄 radiusclient.cxx
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2001 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const radiusClient_cxx_Version = "$Id: radiusClient.cxx,v 1.12.2.1 2003/02/05 02:23:15 bko Exp $";#include <cstdio>#ifdef __FreeBSD__#include <sys/types.h>#endif#include <netinet/in.h>#include "cpLog.h"#include "UdpStack.hxx"#include "TimeFunc.hxx"#include "RadiusMessage.hxx"#include "RadiusTestConfiguration.hxx"intmain( int argc, char* argv[] ){ string configFile = "client.cfg"; if( argc > 1 ) { configFile = argv[1]; } cout << "RADIUS Client" << endl; RadiusTestConfiguration* config; try { RadiusTestConfiguration::instance( configFile ); config = RadiusTestConfiguration::instance(); } catch( VRadiusException &e ) { cerr << "Cannot read configuration data file " << configFile << endl; exit( -1 ); } if( config->type() != "client" ) { cerr << "Invalid type in " << configFile << endl; exit( -2 ); } if( config->log_file() != "" ) { cpLogOpen( config->log_file().c_str() ); } cpLogSetPriority( config->log_level() ); bool test_access = config->test_access(); bool test_accounting = config->test_accounting(); NetworkAddress serverAddress( config->server_host(), config->server_port() ); NetworkAddress serverAccountingAddress( config->server_host(), config->server_accounting_port() ); char hostName[ 256 ]; if( gethostname( hostName, 255 ) != 0 ) { cerr << "gethostname failed " << endl; exit( -3 ); } NetworkAddress clientAddress( hostName, config->client_port() ); UdpStack s( 0, clientAddress.getPort() ); int response_timeout = config->response_timeout() * 1000; // ms to us // int Acct_Session_Time = config->Acct_Session_Time(); // int Acct_Terminate_Cause = config->Acct_Terminate_Cause(); // Client Data char secret[256]; strncpy( secret, config->secret().c_str(), config->secret().size()+1 ); RadiusData User_Name( config->User_Name().c_str(), config->User_Name().size() ); RadiusData User_Password( config->User_Password().c_str(), config->User_Password().size() ); RadiusData Called_Station_Id( config->Called_Station_Id().c_str(), config->Called_Station_Id().size() ); RadiusData Calling_Station_Id( config->Calling_Station_Id().c_str(), config->Calling_Station_Id().size() ); int numberOfPackets = config->number_of_packets(); // Counters int accessRequest = 0; // Client send int accessAccept = 0; // Server send int accessReject = 0; // Server send int accountingRequest = 0; // Client send int accountingResponse = 0; // Server send NetworkAddress radiusServer; int maxPacketSize = RadiusMaxPacketSize; // u_int8_t reqAuth[ RadiusAuthenticatorLength ]; RawMessage rawMsg; int packetLength; u_int8_t id = 0; RadiusAttribute attrUserName( RA_USER_NAME, User_Name ); RadiusAttribute attrUserPassword( RA_USER_PASSWORD, User_Password ); u_int32_t ip( clientAddress.getIp4Address() ); RadiusData valNasIpAddress( &ip , sizeof(ip) ); RadiusAttribute attrNasIpAddress( RA_NAS_IP_ADDRESS, valNasIpAddress ); u_int32_t port( htonl( clientAddress.getPort() ) ); RadiusData valNasPort( &port , sizeof(port) ); RadiusAttribute attrNasPort( RA_NAS_PORT, valNasPort ); u_int32_t serviceType( htonl(RAST_LOGIN) ); RadiusData valServiceType( &serviceType , sizeof(serviceType) ); RadiusAttribute attrServiceType( RA_SERVICE_TYPE, valServiceType ); RadiusAttribute attrCallee( RA_CALLED_STATION_ID, Called_Station_Id ); RadiusAttribute attrCaller( RA_CALLING_STATION_ID, Calling_Station_Id ); RadiusData valAcctSessionId( "f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com", 48 ); RadiusAttribute attrAcctSessionId( RA_ACCT_SESSION_ID, valAcctSessionId ); u_int32_t portType( htonl(RANPT_VIRTUAL) ); RadiusData valNasPortType( &portType , sizeof(portType) ); RadiusAttribute attrNasPortType( RA_NAS_PORT_TYPE, valNasPortType ); RadiusAttribute attrClass( RA_CLASS, RadiusData( "Nas Ip:1.4.61.70", 16 ) ); FunctionTimer tTotal; tTotal.start(); for( ; ; ) { if( test_access ) { RadiusMessage accessReqMsg( RP_ACCESS_REQUEST ); // Warning: assert is used for testing only assert( accessReqMsg.add( attrUserName ) ); assert( accessReqMsg.add( attrUserPassword ) ); assert( accessReqMsg.add( attrNasIpAddress ) ); // assert( accessReqMsg.add( attrNasPort ) ); assert( accessReqMsg.add( attrServiceType ) ); // assert( accessReqMsg.add( attrCallee ) ); // assert( accessReqMsg.add( attrCaller ) ); assert( accessReqMsg.add( attrNasPortType ) ); accessReqMsg.setIdentifier( ++id ); accessReqMsg.calcAuthenticator( secret ); const u_int8_t* reqAuth = accessReqMsg.getAuthenticator(); cpLog( LOG_DEBUG, "Send\n[%s]", accessReqMsg.verbose().c_str() ); s.transmitTo( reinterpret_cast<const char *>(accessReqMsg.data().buffer), ntohs(accessReqMsg.data().msgHdr.length), &serverAddress ); accessRequest++; packetLength = s.receiveTimeout( reinterpret_cast<char *>(rawMsg.buffer), maxPacketSize, &radiusServer, 0, response_timeout); if( packetLength >= RadiusMinPacketSize ) { RadiusData msgRecvd( rawMsg.buffer, ntohs(rawMsg.msgHdr.length) ); try { RadiusMessage accessResp( msgRecvd, secret ); if( accessResp.type() == RP_ACCESS_ACCEPT ) { if( accessResp.verifyResponseAuthenticator( reqAuth, secret ) ) { try { attrClass = accessResp.get( RA_CLASS ); } catch( VRadiusException &e ) { cpLog( LOG_ERR, "Access Response: %s", e.getDescription().c_str() ); } accessAccept++; } else { cpLog( LOG_ERR, "Cannot verify Response Authenticator" ); } } else if( accessResp.type() == RP_ACCESS_REJECT ) { if( accessResp.verifyResponseAuthenticator( reqAuth, secret ) ) { accessReject++; } else { cpLog( LOG_ERR, "Cannot verify Response Authenticator" ); } } else { cpLog( LOG_ERR, "Unexpected message %d", accessResp.type() ); } cpLog( LOG_DEBUG, "Recv\n[%s]", accessResp.verbose().c_str() ); } catch( VRadiusException &e ) { cpLog( LOG_ERR, "Access Response: %s", e.getDescription().c_str() ); } } else if( packetLength == 0 ) { cpLog( LOG_ERR, "Receive timeout" ); } else if( packetLength > 0 ) { cpLog( LOG_ERR, "Received invalid packet" ); } else { cpLog( LOG_ERR, "UDP stack error" ); } } if( test_accounting ) { RadiusMessage acctReqMsg( RP_ACCOUNTING_REQUEST ); // Warning: assert is used for testing only assert( acctReqMsg.add( attrUserName ) ); assert( acctReqMsg.add( attrNasIpAddress ) ); // assert( acctReqMsg.add( attrNasPort ) ); assert( acctReqMsg.add( attrClass ) ); assert( acctReqMsg.add( attrCallee ) ); assert( acctReqMsg.add( attrCaller ) ); u_int32_t acctType( htonl(RAS_START) ); RadiusData valAcctStatus( &acctType, sizeof(acctType) ); RadiusAttribute attrAcctStatus( RA_ACCT_STATUS_TYPE, valAcctStatus ); assert( acctReqMsg.add( attrAcctStatus ) ); assert( acctReqMsg.add( attrAcctSessionId ) ); assert( acctReqMsg.add( attrNasPortType ) ); acctReqMsg.setIdentifier( ++id ); acctReqMsg.calcAuthenticator( secret ); const u_int8_t* reqAuth = acctReqMsg.getAuthenticator(); cpLog( LOG_DEBUG, "Send\n[%s]", acctReqMsg.verbose().c_str() ); s.transmitTo( reinterpret_cast<const char *>(acctReqMsg.data().buffer), ntohs(acctReqMsg.data().msgHdr.length), &serverAccountingAddress ); accountingRequest++; packetLength = s.receiveTimeout( reinterpret_cast<char *>(rawMsg.buffer), maxPacketSize, &radiusServer, 0, response_timeout); if( packetLength >= RadiusMinPacketSize ) { RadiusData msgRecvd( rawMsg.buffer, ntohs(rawMsg.msgHdr.length) ); try { RadiusMessage acctResp( msgRecvd, secret ); if( acctResp.type() == RP_ACCOUNTING_RESPONSE ) { if( acctResp.verifyResponseAuthenticator( reqAuth, secret ) ) { accountingResponse++; } else { cpLog( LOG_ERR, "Cannot verify Response Authenticator" ); } } else { cpLog( LOG_ERR, "Unexpected message %d", acctResp.type() ); } cpLog( LOG_DEBUG, "Recv\n[%s]", acctResp.verbose().c_str() ); } catch( VRadiusException &e ) { cpLog( LOG_ERR, "Accounting Response: %s", e.getDescription().c_str() ); } } else if( packetLength == 0 ) { cpLog( LOG_ERR, "Receive timeout" ); } else if( packetLength > 0 ) { cpLog( LOG_ERR, "Received invalid packet" ); } else { cpLog( LOG_ERR, "UDP stack error" ); } } if( numberOfPackets < 0 ) { printf( "\rAccess Req: %d Accept: %d Rej: %d Acct Req: %d Resp: %d", accessRequest, accessAccept, accessReject, accountingRequest, accountingResponse ); fflush(stdout); } if( (accessAccept + accessReject + accountingResponse) == numberOfPackets ) { cout << endl; tTotal.end(); //tTotal.print( "tTotal" ); cout << "Access Req: " << accessRequest << " Accept: " << accessAccept << " Rej: " << accessReject << " Acct Req: " << accountingRequest << " Resp: " << accountingResponse << endl; // uncomment the following lines for purify // cout << endl << "Wait...." << endl; // sleep( 180 ); // cout << "Done" << endl; exit( 1 ); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -