accessing subtypes (tlv)

Alan DeKok aland at deployingradius.com
Thu May 16 00:03:49 CEST 2013


Juan Pablo L. wrote:
> Hi, i have downloaded and installed freeradius from git master
> FreeRADIUS Version 3.0.0 (git #7a9281c), 
> i m developing a module to do some charging based on 3gpp2 standards for
> a cdma network, 

  That seems nice.

> i have modified the dictionary to reflect a subtype in one of the
> attributes: 
> 
> ATTRIBUTE      3GPP2-Prepaid-acct-Capability           91       tlv
> ATTRIBUTE       3GPP2-Prepaid-acct-Capability-AvailableInClient   91.1  
>   integer

  OK.  That should work.

> but i m having trouble
> accesing 3GPP2-Prepaid-acct-Capability-AvailableInClient, 
> basically i dont know how and i cant find an example in the code so far.

  The rest of the code largely doesn't look up TLVs.  So there are no
examples.

> when i do:
> 
> ppac = pairfind(request->packet->vps,91.1,5535,TAG_ANY)

  Well... that won't work.  "99.1" is a float, and the function takes an
integer.

  The FreeRADIUS code packs multiple TLV numbers into a 32-bit "int" via
various horrible packing mechanisms.  You don't want to know how that
packing is done...

  You *can* look up attributes by name, though.

> they both return null.

  The first one should also return a compile error.  That should be a
red flag saying "this is wrong".

> any hint will be appreciated as to how can i
> access the values in the subtypes
> of any tlv-type attribute. the other option is just put back the
> dictionary to octect type and access the values manually
> but i know this version of freeradius supports tlv so i would like to
> find a way to do it using freeradius 

  My $0.02 is to look up the name when the module starts, and then cache
it.:

typedef struct rlm_foo_t {
   DICT_ATTR const *ppa_cap;
   ...
} rlm_foo_t;

  Then in the "instantiate" routine, do:

inst->ppa_cap =
dict_attrbyname("3GPP2-Prepaid-acct-Capability-AvailableInClient");


  Then in the lookup code, do:

pairfind(request->packet->vps, inst->ppa_cap->attr,
	 inst->ppa_cap->vendor, TAG_ANY);

  Which is a bit more awkward, but it should work.

  I would also suggest paying *close* attention to compiler warnings.
Passing "99.1" to a function expecting an "int" should cause you to
re-think your entire approach.

  Alan DeKok.


More information about the Freeradius-Users mailing list