[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

11.2.4.1 Examples of Various Rewrite Functions

The examples found in this chapter are working functions that can be used with various existing NAS types. They are taken from the `rewrite' file contained in distribution of GNU Radius.

1. Port rewriting for MAX Ascend terminal servers

Some MAX Ascend terminal servers pack additional information into the NAS-Port-Id attribute. The port number is constructed as XYYZZ, where X = 1 for digital, X = 2 for analog, YY is the line number (1 for first PRI/T1/E1, 2 for second, and so on), and ZZ is the channel number (on the PRI or channelized T1/E1).

The following rewrite functions are intended to compute the integer port number in the range (1 .. portcnt), where portcnt represents the real number of physical ports available on the NAS. Such a port number can be used, for example, to create a dynamic pool of IP addresses (see section 14.1.8 Framed-IP-Address).

 
/*
 * decode MAX port number
 * input: P        --  The value of NAS-Port-Id attribute
 *        portcnt  --  number of physical ports on the NAS
 */
integer
max_decode_port(integer P, integer portcnt)
{
    if (P > 9999) {
        integer s, l, c;

        s = P / 10000;
        l = (P - (10000 * s))/100; 
        c = P - ((10000 * s) + (100 * l)); 
        return (c-1) + (l-1) * portcnt;
    }
    return P;
}

/*
 * Interface function for MAX terminal server with 23 ports.
 * Note that it saves the received NAS-Port-Id attribute in
 * the Orig-NAS-Port-Id attribute. The latter must be
 * defined somewhere in the dictionary
 */
integer
max_fixup()
{
    %[Orig-NAS-Port-Id] = %[NAS-Port-Id];
                                  # Preserve original data
    %[NAS-Port-Id] = max_decode_port(%[NAS-Port-Id], 23);
    return 0;
}

2. Session ID parsing for Cisco AS 5300 series

Cisco VOIP IOS encodes a lot of other information into its Acct-Session-Id. The pieces of information are separated by `/' characters. The part of Acct-Session-Id up to the first `/' character is the actual session ID.

On the other hand, its accounting packets lack NAS-Port-Id, though they may contain the vendor-specific pair with code 2 (vendor PEC 9), which is a string in the form `ISDN 9:D:999' (`9' represents any decimal digit). The number after the last `:' character can be used as a port number.

The following code parses Acct-Session-Id attribute and stores the information it contains in various other attributes, generates a normal Acct-Session-Id, and attempts to generate a NAS-Port-Id attribute.

 
/* 
 * The port rewriting function for Cisco AS5300 used for
 * VoIP. This function is used to generate NAS-Port-Id pair
 * on the basis of vendor-specific pair 2. If the latter is
 * in the form "ISDN 9:D:999" (where each 9 represents a
 * decimal digit), then the function returns the number
 * after the last colon. This is used as a port number.
 */
integer
cisco_pid(string A)
{
    if (A =~ 
        ".*\([0-9][0-9]*\):
         [A-Z0-9][A-Z0-9]*:\([0-9][0-9]*\)") {
        return (integer)\2;
    }
    return -1;
}

/*
 * This function parses the packed session id.
 * The actual sid is the number before the first slash
 * character.  Other possibly relevant fields are also
 * parsed out and saved in the Voip-* A/V pairs. The latter
 * should be defined somewhere in the dictionary.
 * Note that the regular expression in this example
 * spans several lines for readability. It should be on one 
 * line in real file.
 */
string
cisco_sid(string S)
{
   if (S =~ "\(.[^/]*\)/[^/]*/[^/]*/\([^/]*\)/\([^/]*\)/
             \([^/]*\)/\([^/]*\)/\([^/]*\)/\([^/]*\)
             /\([^/]*\).*") {
        %[Voip-Connection-ID] = \2;
        %[Voip-Call-Leg-Type] = \3;
        %[Voip-Connection-Type] = \4;
        %[Voip-Connect-Time] = \5;
        %[Voip-Disconnect-Time] = \6;
        %[Voip-Disconnect-Cause] = \7;
        %[Voip-Remote-IP] = \8;
        return \1;
   } 
   return S;
}

/*
 * Normalize cisco AS5300 packets
 */
integer
cisco_fixup()
{
    integer pid;

    if ((pid = cisco_pid(%[Cisco-PRI-Circuit])) != -1) {
        if (*%[NAS-Port-Id])
            %[Orig-NAS-Port-Id] = %[NAS-Port-Id];
        %[NAS-Port-Id] = pid;
    }
    if (*%[Acct-Session-Id]) {
        %[Orig-Acct-Session-Id] = %[Acct-Session-Id];
        %[Acct-Session-Id] = cisco_sid(%[Acct-Session-Id]);
    }
    return 0;
}

3. User-name rewriting for NT machines

Users coming from Windows NT machines often authenticate themselves as `NT_DOMAIN\username'. The following function selects the user-name part and stores it in the User-Name attribute:

 
integer
login_nt(string uname)
{
    integer i;
        
    if ((i = index(uname, '\\')) != -1)
        return substr(uname, i+1, -1);
    return uname;
}

integer
nt_rewrite()
{
    %[Orig-User-Name] = %[User-Name];
    %[User-Name] = login_nt(%[User-Name]);
    return 0;
}


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Sergey Poznyakoff on November, 20 2004 using texi2html