Lua script context API - RADIUS sub-context
radius
RADIUS packet data.
Fields
| Field | Type | Description |
|---|---|---|
request | packet | RADIUS request packet |
reply | packet | RADIUS reply packet |
dynauth | packet | Dynamic authorization packet |
client | client? | RADIUS client info |
server | server? | RADIUS server info |
Packet Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
attr(name, tag?) | attribute name, optional tag | value? | Get first attribute value |
attr_last(name, tag?) | attribute name, optional tag | value? | Get last attribute value |
attr_all(name, tag?) | attribute name, optional tag | values | Get all attribute values as an array |
attrs() | - | table | Get all attributes as a table |
append_attr(name, tag?, value) | name, tag, value | - | Append attribute (reply only) |
append_attrs(name, tag?, values) | name, tag, values | - | Append multiple values (reply only) |
set_attr(name, tag?, value) | name, tag, value | - | Set attribute if not exists (reply only) |
set_attrs(name, tag?, values) | name, tag, values | - | Set multiple values (reply only) |
Attribute Names
All attribute names are stored in lowercase by the RADIUS dictionary parser
regardless of how they appear in the dictionary file or the RADIUS packet.
Always use lowercase names when calling attr(), attr_last(), attr_all(),
and the write methods.
-- Correct: lowercase
local ip = radius.request:attr("framed-ip-address")
local nas = radius.request:attr("nas-identifier")
local mac = radius.request:attr("calling-station-id")
local user = radius.request:attr("user-name")
-- Wrong: mixed-case returns nil
-- local ip = radius.request:attr("Framed-IP-Address") -- nil
Note: radconf condition expressions (
radius.request.attr.Framed-IP-Address) and template expansions (%{radius.request.attr.Framed-IP-Address}) use a separate code path and are not affected by this lowercasing requirement.
attrs() Return Value
attrs() returns a Lua table where each key is a lowercase attribute name
(string) and each value is an array (table with integer keys starting at 1)
containing all occurrences of that attribute.
Attribute values are mapped to Lua types as follows:
| RADIUS type | Lua type |
|---|---|
| Integer / Unsigned | number |
| Text / String | string |
| IP address / network | string (dotted-decimal or CIDR) |
| Bytes / binary | string (raw bytes) |
| Boolean | boolean |
| Missing / unknown | nil |
Single-occurrence attributes still appear as a one-element array so you can always iterate uniformly:
local all = radius.request:attrs()
-- all["user-name"] -> { "alice" }
-- all["framed-ip-address"] -> { "10.0.0.5" }
-- all["class"] -> { "group1", "group2" } (multi-value)
-- Inspect every attribute and its values
for name, values in pairs(all) do
for _, v in ipairs(values) do
context:log("AUTHLOG", name .. " = " .. tostring(v))
end
end
Client Object
| Field | Type | Description |
|---|---|---|
name | string | Client name |
ip | string? | Client IP address |
Server Object
| Field | Type | Description |
|---|---|---|
name | string | Server name |
ip | string | Server IP address |
port | number | Server port |
tls | boolean | Is TLS enabled? |
Example
local context, previous = ...
local radius = context.radius
-- Read request attributes (use lowercase names)
local username = radius.request:attr("user-name")
local nas_ip = radius.request:attr("nas-ip-address")
local framed = radius.request:attr("framed-ip-address")
-- Get all values of a multi-value attribute
local all_filters = radius.request:attr_all("filter-id")
if all_filters then
for _, f in ipairs(all_filters) do
context:log("AUTHLOG", "Filter: " .. tostring(f))
end
end
-- Dump every attribute in the request for debugging
local all = radius.request:attrs()
for name, values in pairs(all) do
for _, v in ipairs(values) do
context:log("AUTHLOG", name .. " = " .. tostring(v))
end
end
-- Add reply attributes
radius.reply:append_attr("reply-message", nil, "Welcome!")
radius.reply:set_attr("session-timeout", nil, 3600)
-- Check client
if radius.client then
local client_name = radius.client.name
local client_ip = radius.client.ip
end
return previous