Dictionary Reference
The dictionary is what pyrad2 reads to translate User-Name into "attribute code 1, type string" and back. This page documents every dictionary feature pyrad2 understands.
For a hands-on tour, run examples/dictionary_features.py - backed by examples/dictionary.extended - which exercises every feature below:
Goal
pyrad2 aims to load real-world FreeRADIUS dictionaries without modification. If a dictionary works in FreeRADIUS, it should work here too.
Data types
Use these in the third column of an ATTRIBUTE declaration:
| Type | Description |
|---|---|
string |
UTF-8 text |
octets |
Raw bytes |
integer |
32-bit unsigned integer |
signed |
32-bit signed integer |
short |
16-bit unsigned integer |
byte |
8-bit unsigned integer |
integer64 |
64-bit unsigned integer |
date |
Seconds since the Unix epoch |
ipaddr |
IPv4 address |
ipv6addr |
IPv6 address |
ipv6prefix |
IPv6 prefix |
ifid |
8-byte Interface-Id (RFC 3162) |
ether |
MAC address (RFC 6911) |
abinary |
Ascend filter format |
tlv |
TLV container (one level of nesting) |
extended |
RFC 6929 wrapper (types 241–244) |
long-extended |
RFC 6929 wrapper (types 245–246) - transparent fragmentation |
Attribute options
Add comma-separated options after the type column:
| Option | Effect |
|---|---|
has_tag |
Attribute carries a one-byte tag prefix (RFC 2868) |
encrypt=1 |
User-Password obfuscation |
encrypt=2 |
Tunnel-Password / MS-MPPE-Key obfuscation |
encrypt=3 |
Ascend-Send / Ascend-Receive obfuscation |
concat |
Values > 253 bytes split across multiple AVPs on the wire (RFC 7268 §3.6) - typical for EAP-Message, CHAP-Challenge |
Vendor-specific format
Per-vendor VSA wire format is honored end-to-end. Declare it on the VENDOR line:
The format=type_len,len_len directive controls:
type_len- bytes in the vendor-type field:1,2, or4len_len- bytes in the vendor-length field:0,1, or2
If format= is omitted, pyrad2 falls back to the RFC 2865 §5.26 default of 1,1.
Extended attributes (RFC 6929)
RFC 6929 reserves attribute types 241–246 as wrappers that hold sub-attributes. Declare the wrapper, then add sub-attributes using dotted-code notation:
ATTRIBUTE Extended-Attribute-1 241 extended
ATTRIBUTE Frag-Status 241.1 integer
ATTRIBUTE Auth-Lifetime 241.2 integer
ATTRIBUTE Extended-Attribute-5 245 long-extended
ATTRIBUTE WiMAX-Blob 245.1 octets
| Type | Use |
|---|---|
extended (241–244) |
Standard extended attribute |
long-extended (245–246) |
Extended attribute with fragmentation for values > 251 bytes |
Access on the packet
Sub-attributes are accessed by name; the parent returns a dict of sub-attribute values:
packet["Frag-Status"] = 5
packet["Auth-Lifetime"] = 3600
packet["Extended-Attribute-1"]
# -> {"Frag-Status": [5], "Auth-Lifetime": [3600]}
long-extended values larger than 251 bytes are fragmented on send and reassembled on receive. Callers see one logical value either way.
Extended-Vendor-Specific (EVS)
EVS (RFC 6929 §2.3) is how a vendor carries its own attributes inside an extended wrapper. The evs type marks the slot, and BEGIN-VENDOR <name> parent=<evs-attr> scopes the vendor's attributes underneath it:
ATTRIBUTE Extended-Attribute-1 241 extended
ATTRIBUTE Extended-Vendor-Specific-1 241.26 evs
VENDOR Example 12345
BEGIN-VENDOR Example parent=Extended-Vendor-Specific-1
ATTRIBUTE Example-Attr-1 1 string
ATTRIBUTE Example-Attr-2 2 integer
END-VENDOR Example
Access EVS attributes by name like any other attribute:
The wire encoding wraps the vendor id and vendor type into the extended payload. long-extended EVS values fragment and reassemble the same way as plain long-extended attributes.
Not yet supported
- TLV nesting deeper than two levels.
If you hit something else that FreeRADIUS handles but pyrad2 doesn't, please open an issue.