This is an, I hope, comprehensive writeup on how to configure a Cisco gateway to send RADIUS Accounting details to a RADIUS server running FreeRadius. Among other things, these RADIUS packets contain <a href="http://www.cisco.com/en/US/docs/ios/voice/cdr/developer/guide/cdrdefs.html#wp1011077">useful information about the quality of the audio</a> as perceived by the calling and called parties of the call.
First we have to configure the Cisco hardware to send the RADIUS packets. I'm using a Cisco AS5350XM configured to send only RADIUS accounting details at the end of the call. Note that although the configuration suggests as much, you're not required to use H.323, SIP will also work just as well.
aaa new-model
aaa group server radius voip-accounting
server [ip address] auth-port 1812 acct-port 1813
ip radius source-interface GigabitEthernet0/0
aaa accounting connection h323 stop-only group voip-accounting
radius-server host [ip address] auth-port 1812 acct-port 1813 key 7 [secret]
radius-server vsa send accounting
Note how I'm telling it basically the same thing twice. Apparently this is really necessary, haven't had the time to properly test. This was the easy part.
Setting "aaa new-model" is, as far as I know, required but it will also mess up the way logging in to your Cisco equipment works. Setting this will mean that you will need a username + password combination to log in and the enable password, instead of just a password and the enable password.
Now make sure FreeRADIUS is up and running on a server reachable by the Cisco hardware. Edit /etc/freeradius/radiusd and make sure that the "with_cisco_vsa_hack" is set to yes:
with_cisco_vsa_hack = yes
Edit /etc/freeradius/dictionary so that the Cisco dictionary is NOT specifically loaded
$INCLUDE /usr/share/freeradius/dictionary
Add the following to the dictionary file to be able to use the values the Cisco equipment is sending you (there's lots more information in the RADIUS packets, this is just what I needed):
ATTRIBUTE coder-type-rate 118 string Cisco
ATTRIBUTE hiwater-playout-delay 119 string Cisco
ATTRIBUTE lowater-playout-delay 120 string Cisco
ATTRIBUTE round-trip-delay 121 string Cisco
ATTRIBUTE late-packets 122 string Cisco
ATTRIBUTE lost-packets 123 string Cisco
ATTRIBUTE early-packets 124 string Cisco
I had to make sure the numbers didn't overlap with the existing values already in the Cisco dictionary. This is kinda important, you don't want to end up with the wrong data in the wrong column. Swapping source and destination numbers is totally possible if you're not careful.
Now it's time to insert a record in the database. For some reason my colleague who setup the radius server inserted the query into /etc/freeradius/sql/mysql/dialup.conf (check the comments). There might be better places. If you only want to save the end of call records, make sure you have no other accounting queries active in the queries file:
accounting_stop_query = "INSERT INTO ${acct_table}
(RadAcctId,
AcctSessionId,
AcctUniqueId,
UserName,
Realm,
NASIPAddress,
CiscoNASPort,
NASPortId,
NASPortType,
AcctStartTime,
AcctStopTime,
AcctSessionTime,
AcctAuthentic,
ConnectInfo_start,
ConnectInfo_stop,
AcctInputOctets,
AcctOutputOctets,
CalledStationId,
CallingStationId,
AcctTerminateCause,
ServiceType,
FramedProtocol,
FramedIPAddress,
AcctStartDelay,
AcctStopDelay,
H323GWId,
H323CallOrigin,
H323CallType,
H323Setuptime,
H323ConnectTime,
H323DisconnectTime,
H323DisconnectCause,
H323RemoteAddress,
H323VoiceQuality,
H323ConfId,
Timestamp,
codec,
hiwater,
lowater,
roundtrip,
plate,
plost,
pearly,
DestinationId )
VALUES (
'',
'%{Acct-Session-Id}',
'%{Acct-Unique-Session-Id}',
'%{SQL-User-Name}',
'%{Realm}',
'%{NAS-IP-Address}',
'%{Cisco-NAS-Port}',
'%{NAS-Port-Id}',
'%{NAS-Port-Type}',
from_unixtime(unix_timestamp('%S')-%{Acct-Session-Time}),
'%S',
'%{Acct-Session-Time}',
'%{Acct-Authentic}',
'',
'%{Connect-Info}',
'%{Acct-Input-Octets}',
'%{Acct-Output-Octets}',
'%{Called-Station-Id}',
'%{Calling-Station-Id}',
'%{Acct-Terminate-Cause}',
'%{Service-Type}',
'%{Framed-Protocol}',
'%{Framed-IP-Address}',
'0',
'%{Acct-Delay-Time}',
'%{h323-remote-address}',
'%{h323-call-origin}',
'%{h323-call-type}',
'%{h323-setup-time}',
'%{h323-connect-time}',
'%{h323-disconnect-time}',
'%{h323-disconnect-cause}',
'%{h323-remote-address}',
'%{h323-voice-quality}',
'%{h323-conf-id}' ,
'%{Timestamp}',
'%{coder-type-rate}',
'%{hiwater-playout-delay}',
'%{lowater-playout-delay}',
'%{round-trip-delay}',
'%{late-packets}',
'%{lost-packets}',
'%{early-packets}',
'%{remote-media-address}'
)"
Note that we only added the last few SQL parameters and somehow FreeRADIUS is able to provide the rest. Make sure you have the correct table name and columns configured (double/triplecheck the query and your table).
The column H323VoiceQuality will contain the so called ICPIF impairment factor. A small writeup of what that means is <a href="http://ccie11440.blogspot.com/2007/11/calculated-planning-impairment-factor.html">here</a>.