Forum Discussion

Demeter_Luo_168's avatar
Demeter_Luo_168
Icon for Nimbostratus rankNimbostratus
May 25, 2016
Solved

What is the meaning of caSa16 at irules binary scan?

Hello Everyone   What is the meaning of "caSa16" at irules's binary scan? Can I change the code "caSa16"?   There are specific irules in below link:   https://devcentral.f5.com/wiki/iRules.R...
  • VernonWells's avatar
    May 25, 2016

    binary uses a template method to translate from Tcl native storage (strings) to binary storage (binary format) or vice versa (binary scan). The template describes the binary layout. In the case of binary scan, each positional element in the description is written to a Tcl variable in Tcl native storage. For loads of detail, see this:

    In your provided example, the template is caSa16. There are 4 positional elements:

    1. c - an 8-bit signed integer [1]
    2. a - a single character [2]
    3. S - a 16-bit signed integer in big-endian format [3]
    4. a16 - a sequence of 16 characters

    After extracting these values from [UDP::payload], these are written, in order, to the following variables:

    1. code
    2. id
    3. len
    4. req_auth

    Thus, after the command is evaluated, $code is a signed 8-bit integer, $id is a single character (I really think this should be extracted as type 'c', since it's generally treated as an integer, but that doesn't really matter, as long as it is later used according to its encoded type), $len is a 16-bit signed integer, and $req_auth is a 16-byte sequence. That corresponds to a RADIUS packet header:

    [1] binary only operates with and on signed integers, regardless of size. To convert a signed twos-complement integer into its unsigned equivalent (most network transmitted integers are unsigned), perform a logical-and on it with all-ones. For an 8-bit integer, that is [expr { $i & 0xff }], for a two-byte integer, it is [expr { $i & 0xffff }], and so forth.

    [2] The precise character encoding (ASCII or some form of unicode) depends on the version of Tcl and declarations. For iRules, it is an 8-bit ASCII character.

    [3] Network byte order is big-endian. A single byte has no endianness (in this sense, since we are describing the order of bytes in an encoded integer) so there is no equivalent for 'c'.

    Notice that, later, this whole exercise is performed in reverse:

     

    set reply [binary format caSa16 5 $id 20 $res_auth]
    

     

    binary format takes Tcl encoded values and transforms them into a byte stream defined by the provided format. It is the same format as above. It creates a byte stream as follows:

    1. a single signed 8-bit integer with a value of 5;
    2. a single 8-bit character (actually, an ASCII integer) with the value of whatever is stored in $id;
    3. a two-byte signed integer with the value of 20;
    4. a 16-byte sequence with the value of whatever is stored in $res_auth.