RADIUS::avp¶
Description¶
This command returns or adds/changes/removes RADIUS attribute-value
pairs. Radius profile must be applied for access to this command.
Syntax¶
RADIUS::avp <attr> [attr_type]
RADIUS::avp <attr> [attr_type] [index x] [vendor-id y] [vendor-type z]
RADIUS::avp delete <attr>
RADIUS::avp delete <attr> [index x] [vendor-id y] [vendor-type z]
RADIUS::avp insert <attr> <value> [attr_type]
RADIUS::avp replace <attr> <value> [attr_type]
RADIUS::avp replace <attr> <value> [attr_type] [index x] [vendor-id y] [vendor-type z]
RADIUS::avp [attr_type]¶
- Returns the value of the specified RADIUS attribute. optional attr_type = ( octet | ip4 | ip6 | integer | string | integer64 | ip4prefix | ip6prefix )
RADIUS::avp [attr_type] [index x] [vendor-id y] [vendor-type z]¶
- RADIUS Vendor-Specific attribute
- Optional attr_type = ( octet | ip4 | ip6 | integer | integer64 | ip4prefix | ip6prefix )
- See example below
- Introduced in Version 11.4.0
RADIUS::avp delete [index x] [vendor-id y] [vendor-type z]¶
- Returns the value of the specified RADIUS Vendor-Specific attribute
- Optional attr_type = ( octet | ip4 | ip6 | integer | integer64 | ip4prefix | ip6prefix )
- See example below
- Introduced in Version 11.4.0
RADIUS::avp insert [attr_type]¶
- Inserts the specified RADIUS attribute and value. optional attr_type = ( octet | ip4 | ip6 | integer | string | integer64 | ip4prefix | ip6prefix )
RADIUS::avp replace [attr_type]¶
- Rewrites the specified RADIUS attribute with new value. optional attr_type = ( octet | ip4 | ip6 | integer | string | integer64 | ip4prefix | ip6prefix )
Note¶
The attr should be supplied as the decimal value 1 to 255 or as the
UPPERCASE strings specified in RFC
2865 and RFC
2866 . The optional attr_type
indicates how a value should be interpreted. Valid types are octet,
string, ip4, ip6, integer, integer64, ip4prefix, and ip6prefix ). An
unknown type is treated as octet.
Examples¶
when CLIENT_DATA {
persist uie [RADIUS::avp 1]
RADIUS::avp replace USER-NAME "foo"
}
This example sends only START and STOP messages to a AAA complex that
can’t handle the full load of accounting updates
when CLIENT_DATA {
set type [RADIUS::avp 40 integer]
switch $type {
1 -
2 {
if { [active_members radius_test_pool] > 0 } {
pool radius_test_pool
}
}
default {
drop
}
}
}
In Version 11.4.0 vendor specific attribute parsing was introduced,
here as an example how to add custom attributes to PEM Session
when RULE_INIT {
set static::DBG_X 1
#http://tools.ietf.org/html/rfc2865
#http://tools.ietf.org/html/rfc2866
array set static::R_AVP {
User_Name 1
User_Password 2
Framed_IP_Address 8
Called_Station_Id 30
Calling_Station_Id 31
}
array set static::ACCOUNTINGT_STATUS_T {
1 START
2 STOP
3 INTERIM_UPDATE
}
array set static::RADIUS_CODE {
4 ACCOUNTING_REQUEST
5 ACCOUNTING_RESPONSE
}
# http://www.3gpp.org/ftp/Specs/archive/29_series/29.061/29061_9b0.zip
array set static::3GGP {
VENDOR_ID 10415
3GPP_IMSI 1
3GPP_IMEISV 20
3GPP_RAT_Type 21
3GPP_User_Location_Info 22
}
}
when CLIENT_DATA {
set radius_code $static::RADIUS_CODE([RADIUS::code])
if {$static::DBG_X}{
log local0. "$radius_code from [IP::client_addr]:[UDP::client_port]"
}
switch $radius_code {
ACCOUNTING_REQUEST {
set user_name [RADIUS::avp $static::R_AVP(User_Name) "string"]
set framed_ip_address [RADIUS::avp $static::R_AVP(Framed_IP_Address) ip4 ]
set accounting_status_t $static::ACCOUNTINGT_STATUS_T([RADIUS::avp 40 "integer"])
switch $accounting_status_t {
START {
set msisdn [RADIUS::avp $static::R_AVP(Calling_Station_Id) "string"]
set imsi [RADIUS::avp 26 "string" \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_IMSI)]
set imeisv [RADIUS::avp 26 "string" \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_IMEISV)]
set rat_type [scan [RADIUS::avp 26 "octet" \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_RAT_Type)] "%c"]
binary scan [RADIUS::avp 26 \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_User_Location_Info) \
] H* 3gpp_user_location_info
PEM::session create $framed_ip_address \
subscriber-id $msisdn \
subscriber-type e164 \
user-name $user_name \
imsi $imsi \
imeisv $imeisv \
tower-id $3gpp_user_location_info \
rat_type $rat_type
if {$static::DBG_X}{
set msg "Accounting-Status-Type: $accounting_status_t"
append msg " PEM::Session create $framed_ip_address subscriber_id $msisdn"
append msg " subscriber_type e164 user_name $user_name"
append msg " imsi $imsi tower_id $3gpp_user_location_info"
append msg " imeisv $imeisv rat_type $rat_type "
log local0. $msg
}
}
STOP {
PEM::session delete $framed_ip_address
if {$static::DBG_X}{
set msg "Accounting-Status-Type: $accounting_status_t"
append msg " PEM::session delete $framed_ip_address"
log local0. $msg
}
}
INTERIM_UPDATE {
set rat_type [scan [RADIUS::avp 26 "octet" \
index 0 \
vendor_id $static::3GGP(VENDOR_ID) \
vendor_type $static::3GGP(3GPP_RAT_Type)] "%c"]
PEM::session info attr $framed_ip_address rat_type $rat_type
if {$static::DBG_X}{
set msg "Accounting-Status-Type: $accounting_status_t"
append msg " PEM::session info attr $framed_ip_address RAT_TYPE $rat_type"
log local0. $msg
}
}
}
}
}
}
See this code when you want to sent a RADIUS Accounting Accept
when RULE_INIT {
set static::secret "linus"
}
when CLIENT_DATA {
# getting base information, see also RFC 2865
#0 1 2 3
#0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#| Code | Identifier | Length |
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#| Authenticator |
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#| Attributes ...
#+-+-+-+-+-+-+-+-+-+-+-+-+-
binary scan [UDP::payload] caSa16 code id len req_auth
# Checking if Radius Code is 4 Accounting-Request
if { $code == 4 } {
# Accounting-Response will be 5, hardcode it
# Accounting Response will be 20 bytes long, hardcode it
# creating ResponseAuth =
# MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
set res_auth [md5 "\x05${id}\x00\x14${req_auth}${static::secret}"]
set reply [binary format caSa16 5 $id 20 $res_auth]
clientside { UDP::respond ${reply}}
# Drop the packet since we are not going to send it anywhere
# If we would, we would not need to sent a reply, right ?
UDP::drop
}
}
Use iRule for PEM:Session and reply
when RULE_INIT {
set static::DBG_X 1
set static::secret "linus"
#http://tools.ietf.org/html/rfc2865
#http://tools.ietf.org/html/rfc2866
array set static::R_AVP {
User_Name 1
User_Password 2
Framed_IP_Address 8
Called_Station_Id 30
Calling_Station_Id 31
}
array set static::ACCOUNTINGT_STATUS_T {
1 START
2 STOP
3 INTERIM_UPDATE
}
array set static::RADIUS_CODE {
4 ACCOUNTING_REQUEST
5 ACCOUNTING_RESPONSE
}
# http://www.3gpp.org/ftp/Specs/archive/29_series/29.061/29061_9b0.zip
array set static::3GGP {
VENDOR_ID 10415
3GPP_IMSI 1
3GPP_IMEISV 20
3GPP_RAT_Type 21
3GPP_User_Location_Info 22
}
}
when CLIENT_DATA {
set radius_code $static::RADIUS_CODE([RADIUS::code])
# getting base information, see also RFC 2865
#0 1 2 3
#0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#| Code | Identifier | Length |
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#| Authenticator |
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#| Attributes ...
#+-+-+-+-+-+-+-+-+-+-+-+-+-
binary scan [UDP::payload] caSa16 code id len req_auth
if {$static::DBG_X}{
log local0. "$radius_code from [IP::client_addr]:[UDP::client_port]"
}
switch $radius_code {
ACCOUNTING_REQUEST {
set user_name [RADIUS::avp $static::R_AVP(User_Name) "string"]
set framed_ip_address [RADIUS::avp $static::R_AVP(Framed_IP_Address) ip4 ]
set accounting_status_t $static::ACCOUNTINGT_STATUS_T([RADIUS::avp 40 "integer"])
switch $accounting_status_t {
START {
set msisdn [RADIUS::avp $static::R_AVP(Calling_Station_Id) "string"]
set imsi [RADIUS::avp 26 "string" \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_IMSI)]
set imeisv [RADIUS::avp 26 "string" \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_IMEISV)]
set rat_type [scan [RADIUS::avp 26 "octet" \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_RAT_Type)] "%c"]
binary scan [RADIUS::avp 26 \
index 0 \
vendor-id $static::3GGP(VENDOR_ID) \
vendor-type $static::3GGP(3GPP_User_Location_Info) \
] H* 3gpp_user_location_info
PEM::session create $framed_ip_address \
subscriber-id $msisdn \
subscriber-type e164 \
user-name $user_name \
imsi $imsi \
imeisv $imeisv \
tower-id $3gpp_user_location_info \
rat_type $rat_type
if {$static::DBG_X}{
set msg "Accounting-Status-Type: $accounting_status_t"
append msg " PEM::Session create $framed_ip_address subscriber_id $msisdn"
append msg " subscriber_type e164 user_name $user_name"
append msg " imsi $imsi tower_id $3gpp_user_location_info"
append msg " imeisv $imeisv rat_type $rat_type "
log local0. $msg
}
}
STOP {
PEM::session delete $framed_ip_address
if {$static::DBG_X}{
set msg "Accounting-Status-Type: $accounting_status_t"
append msg " PEM::session delete $framed_ip_address"
log local0. $msg
}
}
INTERIM_UPDATE {
set rat_type [scan [RADIUS::avp 26 "octet" \
index 0 \
vendor_id $static::3GGP(VENDOR_ID) \
vendor_type $static::3GGP(3GPP_RAT_Type)] "%c"]
PEM::session info attr $framed_ip_address rat_type $rat_type
if {$static::DBG_X}{
set msg "Accounting-Status-Type: $accounting_status_t"
append msg " PEM::session info attr $framed_ip_address RAT_TYPE $rat_type"
log local0. $msg
}
}
}
# Accounting-Response will be 5, hardcode it
# Accounting Response will be 20 bytes long, hardcode it
# creating ResponseAuth =
# MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
set res_auth [md5 "\x05${id}\x00\x14${req_auth}${static::secret}"]
set reply [binary format caSa16 5 $id 20 $res_auth]
clientside { UDP::respond ${reply}}
# Drop the packet since we are not going to send it anywhere
# If we would, we would not need to sent a reply, right ?
UDP::drop
}
}
}
This example shows how to parse multiple nested AVPs
when CLIENT_ACCEPTED {
# this example shows how to parse multiple nested AVPs
for {set i 0; set res ""} {$i < 10} {incr i} {
set avp [ RADIUS::avp 26 "string" index $i vendor-id 10415 vendor-type 13]
if { $avp eq "" }{
break
}
lappend res $avp
}
log local0. "result $res "
}