]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
v4: Convert %(integer: ) to new xlat api (#4014)
authorNick Porter <nick@portercomputing.co.uk>
Tue, 23 Mar 2021 14:51:28 +0000 (14:51 +0000)
committerGitHub <noreply@github.com>
Tue, 23 Mar 2021 14:51:28 +0000 (14:51 +0000)
* Convert %(integer: ) to new xlat api

* Update %(integer: ) tests to new syntax

* Update %(integer: ) syntax in other tests

* Update %(integer: ) syntax in documentation

* Update %(integer: ) syntax in raddb

* Fix handling of xlat alternation using %(<func>:<args>) style children

* IPv4 prefix can be cast the same as IPv4 address

* Correct endian handling of conversion of ethernet to integer

* Minor style fixes

* Typo

Co-authored-by: Arran Cudbard-Bell <a.cudbardb@freeradius.org>
17 files changed:
doc/antora/modules/raddb/pages/sites-available/detail.adoc
doc/antora/modules/reference/pages/xlat/builtin.adoc
man/man5/unlang.5
raddb/mods-config/sql/main/cassandra/queries.conf
raddb/mods-config/sql/main/mssql/queries.conf
raddb/mods-config/sql/main/mysql/queries.conf
raddb/mods-config/sql/main/oracle/queries.conf
raddb/mods-config/sql/main/postgresql/queries.conf
raddb/mods-config/sql/main/sqlite/queries.conf
raddb/sites-available/detail
src/lib/unlang/xlat_builtin.c
src/lib/unlang/xlat_tokenize.c
src/lib/util/value.c
src/tests/keywords/xlat-integer
src/tests/modules/redis_ippool/alloc.unlang
src/tests/modules/redis_ippool/release.unlang
src/tests/modules/redis_ippool/update.unlang

index e7ba944da2844efbe6c1e1526a4b9f306825f0dd..3d73e767f66653e670f3873b6ed1d23fd334772a 100644 (file)
@@ -274,7 +274,7 @@ server detail {
        }
 recv {
        update request {
-               &Acct-Delay-Time := "%{expr:%{%{Acct-Delay-Time}:-0} + %c - %{%{integer:Event-Timestamp}:-%{integer:Packet-Original-Timestamp}}}"
+               &Acct-Delay-Time := "%{expr:%{%{Acct-Delay-Time}:-0} + %c - %{%(integer:%{Event-Timestamp}):-%(integer:%{Packet-Original-Timestamp})}}"
        }
        ok
 }
index 721ff8bf49b7fb4df0ef8bc85f1129e633909440..8110544100bbac4954966d9722dadce7d74bf3e0 100644 (file)
@@ -39,9 +39,9 @@ The length of 192.168.0.2 is 4
 ....
 ====
 
-=== %{integer:<&ref>}
+=== %(integer:<value>)
 
-Print the value of the attribute an integer.
+Convert a value to an integer.
 
 In normal operation, `integer` attributes are printed using the name
 given by a `VALUE` statement in a dictionary. Similarly, date
@@ -53,9 +53,9 @@ converted to an integer. For all other inputs, it returns `0`.
 A common usage is to find the difference between two dates.
 
 For example, if a request contains `Service-Type = Login-User`, the
-expansion of `%{integer:&Service-Type}` will yield `1`, which is the
+expansion of `%(integer:%{Service-Type})` will yield `1`, which is the
 value associated with the `Login-User` name. Using
-`%{integer:&Event-Timestamp}` will return the event timestamp as an
+`%(integer:%{Event-Timestamp})` will return the event timestamp as an
 unsigned 32-bit number.
 
 .Return: _string_
@@ -68,7 +68,7 @@ update {
     &control.Service-Type := Login-User
 }
 update reply {
-    &Reply-Message := "The value of Service-Type is %{integer:&control.Service-Type}"
+    &Reply-Message := "The value of Service-Type is %(integer:%{control.Service-Type})"
 }
 ----
 
index ebb0cb26886ad639b28e8dfe48b02686251f5f9e..03bb9f0b542fa00e5543df15b0dd5ba8a9ff0866 100644 (file)
@@ -808,12 +808,11 @@ then the length also does not exist, instead of being zero.
 
 The "string" is expanded before the length is taken.
 
-.IP %{integer:Attribute-Name}
-The integer value of the Attribute-Name, instead of the enumerated
-name.
+.IP %(integer:Value)
+The integer value of the Value.
 
 e.g. If a request contains "Service-Type = Login-User", the expansion
-of %{integer:Service-Type} will yield "1".
+of %(integer:%{Service-Type}) will yield "1".
 
 .IP %{hex:Attribute-Name}
 The hex value of the Attribute-Name, as a series of hex digits.
index 42e56ba3a89662be9127ceb112ba218aa45f1f94..a94a7167f9a23bc259b018907268672e6e7c350e 100644 (file)
@@ -49,7 +49,7 @@ sql_user_name = "%{User-Name}"
 # distrust the provided Event-Timestamp.
 #event_timestamp_epoch = "%l"
 
-event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
+event_timestamp_epoch = "%{%(integer:%{Event-Timestamp}):-%l}"
 
 # event_timestamp is the SQL snippet for converting an epoch timestamp
 # to an SQL date.
index 2d2a9010b9b4756cd5bc590303efa8aa8edabe04..0cbece561adcc8c020d2f088d7dd8e28d783ca28 100644 (file)
@@ -38,7 +38,7 @@ sql_user_name = "%{User-Name}"
 # distrust the provided Event-Timestamp.
 #event_timestamp_epoch = "%l"
 
-event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
+event_timestamp_epoch = "%{%(integer:%{Event-Timestamp}):-%l}"
 
 # event_timestamp is the SQL snippet for converting an epoch timestamp
 # to an SQL date.
index 4d2c0419178341319482deffc03893978860127f..bc7ace8fe46da681a477bc48068e7e4a0b45409b 100644 (file)
@@ -49,7 +49,7 @@ sql_user_name = "%{User-Name}"
 # distrust the provided Event-Timestamp.
 #event_timestamp_epoch = "%l"
 
-event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
+event_timestamp_epoch = "%{%(integer:%{Event-Timestamp}):-%l}"
 
 # event_timestamp is the SQL snippet for converting an epoch timestamp
 # to an SQL date.
index d6588b951a11c51259352603b8a88aa58a234aa5..261ed011c3f1d1cbb0d41ffa980dc6a204b7c7b4 100644 (file)
@@ -33,7 +33,7 @@ sql_user_name = "%{User-Name}"
 # distrust the provided Event-Timestamp.
 #event_timestamp_epoch = "%l"
 
-event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
+event_timestamp_epoch = "%{%(integer:%{Event-Timestamp}):-%l}"
 
 # event_timestamp is the SQL snippet for converting an epoch timestamp
 # to an SQL date.
index 12fe9404880c4dc024c6b9895e651ec877520ace..0015f096b696517c5d94d0633d51422649f1c70b 100644 (file)
@@ -39,7 +39,7 @@ sql_user_name = "%{User-Name}"
 # distrust the provided Event-Timestamp.
 #event_timestamp_epoch = "%l"
 
-event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
+event_timestamp_epoch = "%{%(integer:%{Event-Timestamp}):-%l}"
 
 # event_timestamp is the SQL snippet for converting an epoch timestamp
 # to an SQL date.
index 2ee1959da692a66713fbf081ed8f2ac513495ee9..f4d84e803640da86e7f2465263657a3dfd338567 100644 (file)
@@ -38,7 +38,7 @@ sql_user_name = "%{User-Name}"
 # distrust the provided Event-Timestamp.
 #event_timestamp_epoch = "%l"
 
-event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
+event_timestamp_epoch = "%{%(integer:%{Event-Timestamp}):-%l}"
 
 # event_timestamp is the SQL snippet for converting an epoch timestamp
 # to an SQL date.
index ca24d2e590a47b188aacece6e8d18d1e6f4dae35..e3bff24e7e2e97f4efa58d892cc74e92d92fee7a 100644 (file)
@@ -225,7 +225,7 @@ server detail {
 #
 recv Accounting-Request {
        update request {
-               &Acct-Delay-Time := "%{expr:%{%{Acct-Delay-Time}:-0} + %c - %{%{integer:Event-Timestamp}:-%{integer:Packet-Original-Timestamp}}}"
+               &Acct-Delay-Time := "%{expr:%{%{Acct-Delay-Time}:-0} + %c - %{%(integer:%{Event-Timestamp}):-%(integer:%{Packet-Original-Timestamp})}}"
        }
 
        #
index 3377c63b303b7a7be2fde368c50359492e01f1c3..57e35f324ae10b382f4e32f127ee7ee8f78f1e29 100644 (file)
@@ -1117,6 +1117,11 @@ static xlat_action_t xlat_func_explode(TALLOC_CTX *ctx, fr_dcursor_t *out,
        return XLAT_ACTION_DONE;
 }
 
+static xlat_arg_parser_t const xlat_func_integer_args[] = {
+       { .required = true, .single = true, .type = FR_TYPE_VOID },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Print data as integer, not as VALUE.
  *
  * Example:
@@ -1124,111 +1129,88 @@ static xlat_action_t xlat_func_explode(TALLOC_CTX *ctx, fr_dcursor_t *out,
 update request {
        &Tmp-IP-Address-0 := "127.0.0.5"
 }
-"%{integer:&Tmp-IP-Address-0}" == 2130706437
+"%(integer:%{Tmp-IP-Address-0})" == 2130706437
 @endverbatim
  * @ingroup xlat_functions
  */
-static ssize_t xlat_func_integer(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
-                                UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                                request_t *request, char const *fmt)
+static xlat_action_t xlat_func_integer(TALLOC_CTX *ctx, fr_dcursor_t *out,
+                                      request_t *request, UNUSED void const *xlat_inst,
+                                      UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
 {
-       fr_pair_t       *vp;
+       fr_value_box_t  *in_vb = fr_dlist_head(in);
 
-       uint64_t        int64 = 0;      /* Needs to be initialised to zero */
-       uint32_t        int32 = 0;      /* Needs to be initialised to zero */
-
-       fr_skip_whitespace(fmt);
-
-       if ((xlat_fmt_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
+       fr_strerror_clear(); /* Make sure we don't print old errors */
+       
+       switch (in_vb->type) {
+       default:
+       error:
+               RPEDEBUG("Failed converting %pV (%s) to an integer", in_vb,
+                        fr_table_str_by_value(fr_value_box_type_table, in_vb->type, "???"));
+               return XLAT_ACTION_FAIL;
+                       
+       case FR_TYPE_NUMERIC:
+               /*
+                *      Ensure enumeration is NULL so that the integer
+                *      version of a box is returned
+                */
+               in_vb->enumv = NULL;
+                       
+               /*
+                *      FR_TYPE_DATE and FR_TYPE_DELTA need to be cast to 
+                *      uin64_t so they're printed in a numeric format.
+                */
+               if ((in_vb->type != FR_TYPE_DATE) || (in_vb->type != FR_TYPE_TIME_DELTA)) break;
+               FALL_THROUGH;
 
-       switch (vp->vp_type) {
-       case FR_TYPE_DATE:
        case FR_TYPE_STRING:
-       {
-               fr_value_box_t vb;
-
-               if (fr_value_box_cast(NULL, &vb, FR_TYPE_UINT64, NULL, &vp->data) < 0) {
-                       RPEDEBUG("Invalid input for printing as an integer");
-                       return -1;
-               }
-
-               return snprintf(*out, outlen, "%" PRIu64, vb.vb_uint64);
-       }
+               if (fr_value_box_cast_in_place(ctx, in_vb, FR_TYPE_UINT64, NULL) < 0) goto error;
+               break;
 
        case FR_TYPE_OCTETS:
-               if (vp->vp_length > 8) {
-                       break;
-               }
+               if (in_vb->vb_length > sizeof(uint64_t)) goto error;
 
-               if (vp->vp_length > 4) {
-                       memcpy(&int64, vp->vp_octets, vp->vp_length);
-                       return snprintf(*out, outlen, "%" PRIu64, htonll(int64));
+               if (in_vb->vb_length > sizeof(uint32_t)) {
+                       fr_value_box_cast_in_place(ctx, in_vb, FR_TYPE_UINT64, NULL);
+                       break;
                }
 
-               memcpy(&int32, vp->vp_octets, vp->vp_length);
-               return snprintf(*out, outlen, "%i", htonl(int32));
-
-       case FR_TYPE_UINT64:
-               return snprintf(*out, outlen, "%" PRIu64, vp->vp_uint64);
+               fr_value_box_cast_in_place(ctx, in_vb, FR_TYPE_UINT32, NULL);
+               break;
 
-       /*
-        *      IP addresses are treated specially, as parsing functions assume the value
-        *      is bigendian and will convert it for us.
-        */
        case FR_TYPE_IPV4_ADDR:
-       case FR_TYPE_IPV4_PREFIX:       /* Same addr field */
-               return snprintf(*out, outlen, "%u", ntohl(vp->vp_ipv4addr));
-
-       case FR_TYPE_UINT32:
-               return snprintf(*out, outlen, "%u", vp->vp_uint32);
-
-       case FR_TYPE_UINT8:
-               return snprintf(*out, outlen, "%u", (unsigned int) vp->vp_uint8);
-
-       case FR_TYPE_UINT16:
-               return snprintf(*out, outlen, "%u", (unsigned int) vp->vp_uint16);
+       case FR_TYPE_IPV4_PREFIX:
+               if (fr_value_box_cast_in_place(ctx, in_vb, FR_TYPE_UINT32, NULL) < 0) goto error;
+               break;
 
-       /*
-        *      Ethernet is weird... It's network related, so it
-        *      should be bigendian.
-        */
        case FR_TYPE_ETHERNET:
-               int64 = vp->vp_ether[0];
-               int64 <<= 8;
-               int64 |= vp->vp_ether[1];
-               int64 <<= 8;
-               int64 |= vp->vp_ether[2];
-               int64 <<= 8;
-               int64 |= vp->vp_ether[3];
-               int64 <<= 8;
-               int64 |= vp->vp_ether[4];
-               int64 <<= 8;
-               int64 |= vp->vp_ether[5];
-               return snprintf(*out, outlen, "%" PRIu64, int64);
-
-       case FR_TYPE_INT32:
-               return snprintf(*out, outlen, "%i", vp->vp_int32);
+               if (fr_value_box_cast_in_place(ctx, in_vb, FR_TYPE_UINT64, NULL) < 0) goto error;
+               break;
 
        case FR_TYPE_IPV6_ADDR:
        case FR_TYPE_IPV6_PREFIX:
        {
-               uint128_t ipv6int;
+               uint128_t       ipv6int;
+               char            buff[40];
+               fr_value_box_t  *vb;
 
                /*
                 *      Needed for correct alignment (as flagged by ubsan)
                 */
-               memcpy(&ipv6int, &vp->vp_ipv6addr, sizeof(ipv6int));
+               memcpy(&ipv6int, &in_vb->vb_ip.addr.v6.s6_addr, sizeof(ipv6int));
 
-               return fr_snprint_uint128(*out, outlen, ntohlll(ipv6int));
-       }
+               fr_snprint_uint128(buff, sizeof(buff), ntohlll(ipv6int));
 
-       default:
-               break;
+               MEM(vb = fr_value_box_alloc_null(ctx));
+               fr_value_box_bstrndup(ctx, vb, NULL, buff, strlen(buff), false);
+               fr_dcursor_append(out, vb);
+               return XLAT_ACTION_DONE;
+       }
        }
 
-       REDEBUG("Type '%s' cannot be converted to integer", fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "???"));
+       fr_dlist_remove(in, in_vb);
+       fr_dcursor_append(out, in_vb);
 
-       return -1;
+       return XLAT_ACTION_DONE;
 }
 
 static xlat_arg_parser_t const xlat_func_map_arg = {
@@ -3169,7 +3151,6 @@ int xlat_init(void)
 #define XLAT_REGISTER(_x) xlat = xlat_register_legacy(NULL, STRINGIFY(_x), xlat_func_ ## _x, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN); \
        xlat_internal(xlat);
 
-       XLAT_REGISTER(integer);
        XLAT_REGISTER(map);
        XLAT_REGISTER(xlat);
 
@@ -3185,6 +3166,7 @@ do { \
        XLAT_REGISTER_ARGS("explode", xlat_func_explode, xlat_func_explode_args);
        XLAT_REGISTER_ARGS("hmacmd5", xlat_func_hmac_md5, xlat_hmac_args);
        XLAT_REGISTER_ARGS("hmacsha1", xlat_func_hmac_sha1, xlat_hmac_args);
+       XLAT_REGISTER_ARGS("integer", xlat_func_integer, xlat_func_integer_args);
        XLAT_REGISTER_ARGS("join", xlat_func_join, xlat_func_join_args);
        XLAT_REGISTER_ARGS("nexttime", xlat_func_next_time, xlat_func_next_time_args);
        XLAT_REGISTER_ARGS("pairs", xlat_func_pairs, xlat_func_pairs_args);
index feceba2a24510b4ac0af6b4787f032b697fdb004..491fc86304e3c258e014bc66a402f06f43908f12 100644 (file)
@@ -215,8 +215,12 @@ static int xlat_tokenize_literal(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_
                                 fr_sbuff_t *in, bool brace,
                                 fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
 
+static inline int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head,
+                                             xlat_flags_t *flags, fr_sbuff_t *in,
+                                             tmpl_rules_t const *rules);
+
 static inline int xlat_tokenize_alternation(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
-                                           tmpl_rules_t const *t_rules)
+                                           tmpl_rules_t const *t_rules, bool func_args)
 {
        xlat_exp_t      *node;
 
@@ -224,11 +228,16 @@ static inline int xlat_tokenize_alternation(TALLOC_CTX *ctx, xlat_exp_t **head,
 
        node = xlat_exp_alloc_null(ctx);
        xlat_exp_set_type(node, XLAT_ALTERNATE);
-       if (xlat_tokenize_expansion(node, &node->child, &node->flags, in, t_rules) < 0) {
-       error:
-               *head = NULL;
-               talloc_free(node);
-               return -1;
+
+       if (func_args) {
+               if (xlat_tokenize_function_args(node, &node->child, &node->flags, in, t_rules) < 0) {
+               error:
+                       *head = NULL;
+                       talloc_free(node);
+                       return -1;
+               }
+       } else {
+               if (xlat_tokenize_expansion(node, &node->child, &node->flags, in, t_rules) < 0) goto error;
        }
 
        if (!fr_sbuff_adv_past_str_literal(in, ":-")) {
@@ -488,7 +497,7 @@ static inline int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head
        XLAT_DEBUG("FUNC <-- %pV", fr_box_strvalue_len(fr_sbuff_current(in), fr_sbuff_remaining(in)));
 
        /*
-        *      %{module:args}
+        *      %(module:args)
         */
        fr_sbuff_marker(&m_s, in);
        fr_sbuff_adv_past_allowed(in, SIZE_MAX, func_chars, NULL);
@@ -734,7 +743,14 @@ static int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flag
         *      %{...}:-bar}
         */
        if (fr_sbuff_adv_past_str_literal(in, "%{")) {
-               return xlat_tokenize_alternation(ctx, head, flags, in, t_rules);
+               return xlat_tokenize_alternation(ctx, head, flags, in, t_rules, false);
+       }
+
+       /*
+        *      %(...):-bar}
+        */
+       if (fr_sbuff_adv_past_str_literal(in, "%(")) {
+               return xlat_tokenize_alternation(ctx, head, flags, in, t_rules, true);
        }
 
        /*
index 8ad0d52942d9af9748385c3ff59602c97e468bbf..a60a29f8de31977bd50488f94d945777f0e4135e 100644 (file)
@@ -2776,6 +2776,7 @@ static inline int fr_value_box_cast_to_integer(TALLOC_CTX *ctx, fr_value_box_t *
                return fr_value_box_cast_integer_to_integer(ctx, dst, dst_type, dst_enumv, src);
 
        case FR_TYPE_IPV4_ADDR:
+       case FR_TYPE_IPV4_PREFIX:
        {
                fr_value_box_t  tmp;
 
@@ -2813,13 +2814,15 @@ static inline int fr_value_box_cast_to_integer(TALLOC_CTX *ctx, fr_value_box_t *
                }
 
                fr_value_box_init(&tmp, FR_TYPE_UINT64, src->enumv, src->tainted);
-#ifdef WORDS_BIGENDIAN
                memcpy(((uint8_t *)&tmp.vb_uint64) + (sizeof(tmp.vb_uint64) - sizeof(src->vb_ether)),
                       &src->vb_ether, sizeof(src->vb_ether));
-#else
-               memcpy(&tmp.vb_uint64, &src->vb_ether, sizeof(tmp.vb_ether));
-#endif
+#ifndef WORDS_BIGENDIAN
+               /*
+                *      Ethernet addresses are always stored bigendian,
+                *      convert to native on little endian systems
+                */
                fr_value_box_hton(&tmp, &tmp);
+#endif
                return fr_value_box_cast_integer_to_integer(ctx, dst, dst_type, dst_enumv, &tmp);
        }
 
index 27611c99eea4e4842073f5a1870485e0d68e634e..2f9125328508eae204e0b0e99486bce6b15cb21c 100644 (file)
@@ -23,7 +23,7 @@ update request {
 
 # String - network order representation of a 4 char string
 update request {
-       &Tmp-Integer-1 := "%{integer:Tmp-String-0}"
+       &Tmp-Integer-1 := "%(integer:%{Tmp-String-0})"
 }
 if ((<integer>&Tmp-String-0 != &Tmp-Integer-1) || (&Tmp-Integer-1 != 9870)) {
        test_fail
@@ -31,20 +31,20 @@ if ((<integer>&Tmp-String-0 != &Tmp-Integer-1) || (&Tmp-Integer-1 != 9870)) {
 
 # String - network order representation of a 8 char string
 update request {
-       &Tmp-Integer64-0 := "%{integer:Tmp-String-1}"
+       &Tmp-Integer64-0 := "%(integer:%{Tmp-String-1})"
 }
 if ((<integer64>&Tmp-String-1 != &Tmp-Integer64-0) || (&Tmp-Integer64-0 != 98709870)) {
        test_fail
 }
 
 # String - Can't convert 12 byte string to integer (our biggest native size is a 64bit unsigned int)
-if ("%{integer:Tmp-String-2}" != '') {
+if ("%(integer:%{Tmp-String-2})" != '') {
        test_fail
 }
 
 # Octets - network order representation of a 4 byte octet string
 update request {
-       &Tmp-Integer-1 := "%{integer:Tmp-Octets-0}"
+       &Tmp-Integer-1 := "%(integer:%{Tmp-Octets-0})"
 }
 
 #
@@ -59,7 +59,7 @@ if (&Tmp-Integer-1 != 959985457) {
 
 # Octets - network order representation of a 8 byte octet string
 update request {
-       &Tmp-Integer64-0 := "%{integer:Tmp-Octets-1}"
+       &Tmp-Integer64-0 := "%(integer:%{Tmp-Octets-1})"
 }
 
 #
@@ -74,17 +74,17 @@ if (&Tmp-Integer64-0 != 4123106143410599729) {
 }
 
 # String - Can't convert 12 byte octet string to integer (our biggest native size is a 64bit unsigned int)
-if ("%{integer:Tmp-Octets-2}" != '') {
+if ("%(integer:%{Tmp-Octets-2})" != '') {
        test_fail
 }
 
 update request {
-       &Tmp-String-2        := "%{integer:Tmp-IP-Address-0}"
-       &Tmp-String-3        := "%{integer:Tmp-Date-0}"
-       &Tmp-String-4        := "%{integer:Tmp-Integer-0}"
-       &Tmp-String-6        := "%{integer:Tmp-Cast-Ifid}"
-       &Tmp-String-7        := "%{integer:Tmp-Cast-IPv6Addr}"
-       &Tmp-String-8        := "%{integer:Tmp-Cast-IPv6Prefix}"
+       &Tmp-String-2        := "%(integer:%{Tmp-IP-Address-0})"
+       &Tmp-String-3        := "%(integer:%{Tmp-Date-0})"
+       &Tmp-String-4        := "%(integer:%{Tmp-Integer-0})"
+       &Tmp-String-6        := "%(integer:%{Tmp-Cast-Ifid})"
+       &Tmp-String-7        := "%(integer:%{Tmp-Cast-IPv6Addr})"
+       &Tmp-String-8        := "%(integer:%{Tmp-Cast-IPv6Prefix})"
 }
 
 # IP Address
@@ -121,11 +121,11 @@ if (&Tmp-String-8 != '959985465') {
        test_fail
 }
 update request {
-       &Tmp-String-0        := "%{integer:Tmp-Cast-Byte}"
-       &Tmp-String-1        := "%{integer:Tmp-Cast-Short}"
-       &Tmp-Integer64-2     := "%{integer:Tmp-Cast-Ether}"
-       &Tmp-String-3        := "%{integer:Tmp-Cast-Integer64}"
-       &Tmp-String-4        := "%{integer:Tmp-Cast-IPv4Prefix}"
+       &Tmp-String-0        := "%(integer:%{Tmp-Cast-Byte})"
+       &Tmp-String-1        := "%(integer:%{Tmp-Cast-Short})"
+       &Tmp-Integer64-2     := "%(integer:%{Tmp-Cast-Ether})"
+       &Tmp-String-3        := "%(integer:%{Tmp-Cast-Integer64})"
+       &Tmp-String-4        := "%(integer:%{Tmp-Cast-IPv4Prefix})"
 }
 
 # byte
@@ -162,4 +162,16 @@ if (&Tmp-String-4 != '959985470') {
        test_fail
 }
 
+update request {
+       &Service-Type := Login-User
+}
+
+update request {
+       &Tmp-Integer-2 := "%(integer:%{Service-Type})"
+}
+
+if (&Tmp-Integer-2 != 1) {
+       test_fail
+}
+
 success
index 73e7c7d7412a294ba8a237538f8f13ba0830062c..8b3fb47d1c90d42ab83ee83747f77f9808f8d073 100644 (file)
@@ -37,13 +37,13 @@ update request {
        &Tmp-Date-0 := "%l"
 }
 
-if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %{integer:&Tmp-Date-0}}" > 20) {
+if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %(integer:%{Tmp-Date-0})}" > 20) {
        test_pass
 } else {
        test_fail
 }
 
-if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %{integer:&Tmp-Date-0}}" < 40) {
+if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %(integer:%{Tmp-Date-0})}" < 40) {
        test_pass
 } else {
        test_fail
index 6e0088cde29bfe65259411b16191e59d3d2cc5db..5d02dc10d5f848083e344a3ab15a77be0af12087 100644 (file)
@@ -83,13 +83,13 @@ update request {
        &Tmp-Date-0 := "%l"
 }
 
-if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %{integer:&Tmp-Date-0}}" > 0) {
+if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %(integer:%{Tmp-Date-0})}" > 0) {
        test_pass
 } else {
        test_fail
 }
 
-if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %{integer:&Tmp-Date-0}}" < 10) {
+if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %(integer:%{Tmp-Date-0})}" < 10) {
        test_pass
 } else {
        test_fail
index b1811c8f92c2f49f38790609a98346dd4eb955b5..d5bf6d9bc7c45d0df24e793593ebefd72de90ed7 100644 (file)
@@ -73,14 +73,14 @@ update request {
        &Tmp-Date-0 := "%l"
 }
 
-if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %{integer:&Tmp-Date-0}}" > 50) {
+if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %(integer:%{Tmp-Date-0})}" > 50) {
        test_pass
 } else {
        test_fail
 }
 
 # 9.
-if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %{integer:&Tmp-Date-0}}" < 70) {
+if ("%{expr:%{redis:ZSCORE '{%{control.IP-Pool.Name}%}:pool' '%{reply.Framed-IP-Address}'} - %(integer:%{Tmp-Date-0})}" < 70) {
        test_pass
 } else {
        test_fail