11defmodule Radius.Packet do
2+ @ moduledoc """
3+ This module defines a struct and provides the main functions to encode and decode requests and replies.
4+ """
25 require Logger
36
47 alias __MODULE__
8+ require Radius.Dict
59 alias Radius.Dict
610 alias Radius.Dict.EntryNotFoundError
711
@@ -26,10 +30,17 @@ defmodule Radius.Packet do
2630
2731 @ doc """
2832 Decode radius packet
33+
34+ Options:
35+
36+ * `attributes` - leave attributes as `:integers`, defaults to `:strings`. `:integers` can be
37+ pattern matched with the macro's provided by `Radius.Dict`
2938 """
30- def decode ( data , secret ) do
39+ def decode ( data , secret , opts \\ [ ] ) do
40+ attributes_as = Keyword . get ( opts , :attributes , :strings )
41+
3142 pkt =
32- % { raw: data , secret: secret , attrs: nil }
43+ % { raw: data , secret: secret , attrs: nil , attributes_as: attributes_as }
3344 |> decode_header
3445 |> decode_payload
3546
@@ -68,7 +79,8 @@ defmodule Radius.Packet do
6879 defp decode_code ( x ) , do: x
6980
7081 defp decode_payload ( ctx ) do
71- decode_tlv ( ctx . rest )
82+ ctx . rest
83+ |> decode_tlv ( )
7284 |> resolve_tlv ( ctx )
7385 end
7486
@@ -94,7 +106,13 @@ defmodule Radius.Packet do
94106
95107 # VSA Entry
96108 defp resolve_tlv ( { 26 , value } , ctx , nil ) do
97- type = "Vendor-Specific"
109+ type =
110+ if ctx . attributes_as == :integers do
111+ Dict . attr_Vendor_Specific ( )
112+ else
113+ "Vendor-Specific"
114+ end
115+
98116 << vid :: size ( 32 ) , rest :: binary >> = value
99117
100118 try do
@@ -123,6 +141,13 @@ defmodule Radius.Packet do
123141 attr = vendor_attribute_by_id ( vendor , type )
124142 has_tag = Keyword . has_key? ( attr . opts , :has_tag )
125143
144+ attr_name =
145+ if ctx . attributes_as == :integers do
146+ type
147+ else
148+ attr . name
149+ end
150+
126151 { tag , value } =
127152 case value do
128153 << 0 , rest :: binary >> when has_tag == true ->
@@ -142,9 +167,9 @@ defmodule Radius.Packet do
142167 |> decrypt_value ( Keyword . get ( attr . opts , :encrypt ) , ctx . auth , ctx . secret )
143168
144169 if tag do
145- { attr . name , { tag , value } }
170+ { attr_name , { tag , value } }
146171 else
147- { attr . name , value }
172+ { attr_name , value }
148173 end
149174 rescue
150175 _e in EntryNotFoundError ->
@@ -199,17 +224,17 @@ defmodule Radius.Packet do
199224 end
200225
201226 @ doc """
202- Return an iolist of encoded packet
227+ Return an iolist of encoded packet
203228
204- for request packets, leave packet.auth == nil, then I will generate one from random bytes.
205- for reply packets, set packet.auth = request.auth, I will calc the reply hash with it.
229+ for request packets, leave packet.auth == nil, then I will generate one from random bytes.
230+ for reply packets, set packet.auth = request.auth, I will calc the reply hash with it.
206231
207- packet.attrs :: [attr]
208- attr :: {type,value}
209- type :: String.t | integer | {"Vendor-Specific", vendor}
210- value :: integer | String.t | ipaddr
211- vendor :: String.t | integer
212- ipaddr :: {a,b,c,d} | {a,b,c,d,e,f,g,h}
232+ packet.attrs :: [attr]
233+ attr :: {type,value}
234+ type :: String.t | integer | {"Vendor-Specific", vendor}
235+ value :: integer | String.t | ipaddr
236+ vendor :: String.t | integer
237+ ipaddr :: {a,b,c,d} | {a,b,c,d,e,f,g,h}
213238
214239 """
215240 @ deprecated "Use encode_request/1-2 or encode_reply/1-2 instead"
@@ -239,6 +264,10 @@ defmodule Radius.Packet do
239264 @ doc """
240265 Encode the reply packet into an iolist and put the result in the `:raw` key. The `:auth` key needs
241266 to be filled with the authenticator of the request packet.
267+
268+ Options:
269+
270+ * `sign` - `true` if you want to sign the request, `false` by default
242271 """
243272 @ spec encode_reply (
244273 packet :: Packet . t ( ) ,
@@ -261,7 +290,7 @@ defmodule Radius.Packet do
261290
262291 packet =
263292 if sign? do
264- attrs = [ { "Message-Authenticator" , << 0 :: size ( 128 ) >> } | packet . attrs ]
293+ attrs = [ Dict . attr_Message_Authenticator ( << 0 :: size ( 128 ) >> ) | packet . attrs ]
265294
266295 % { packet | attrs: attrs }
267296 else
@@ -440,8 +469,6 @@ defmodule Radius.Packet do
440469 do: encode_vsa ( Dict . vendor_by_id ( vid ) , vsa , ctx )
441470
442471 defp encode_vsa ( vendor , vsa , ctx ) do
443- IO . inspect ( vendor )
444-
445472 val =
446473 Enum . map ( vsa , fn x ->
447474 x |> resolve_attr ( ctx , vendor ) |> encode_attr ( vendor . format )
0 commit comments