Variable expression evaluation
Variable expression evaluation is an extension to regular expression syntax that provides the ability to use variables, parse values from the traffic stream and perform arithmetic operations.
Sequence | Description |
---|---|
(?[<expression>])
|
<expression> is one or more comma-separated expressions |
Example of setting a variable in a variable expression
# This regular expression searches for "aaa" anywhere in the traffic stream,
# and then sets the value of "parameter1" to 1
.*aaa(?[parameter1=1])
The default variable size is one bit. Variable size can be changed by appending “@<size>
” to the variable name. For example, “parameter1@8
” is an 8-bit variable. Possible variable sizes, in addition to 1, are 8, 16, 32 and 64 bits. By default variables are visible within a situation context. For example, a variable used in a situation with context “HTTP Request URI” is visible to all other situations in that context. Prefixing the variable name with a dollar sign “$” makes it a connection variable. A connection variable is visible in all situations contexts for a single TCP connection, for example in both client and server stream contexts.
By default, no situation match is created when the end of a variable expression in reached. To create a match when a variable expression is used, the “sid()
” function must be called.
Sequence | Description |
---|---|
<varexpr_a> -> <varexpr_b>
|
varexpr_b is executed only if varexpr_a is true |
The following example shows a typical case where we want to search one string followed by another, for example “aaa” followed by “bbb”. An expression such as “.*aaa.*bbb
” breaks the guideline of not using “.*
” in the middle of a regular expression. You can circumvent this issue using variable expressions.
Example of setting and checking a variable value in a variable expression
# This regular expression searches for "aaa" anywhere in the traffic stream,
# and then sets the value of 'my_var' to 1.
# It also searches for "bbb", and checks whether "aaa" has already been
# seen earlier (i.e. the value of 'my_var' is one). If "aaa" has been seen
# already, a match is created using the "sid()" function.
# The following traffic matches this regular expression: "aaabbb",
# "xxaaaxxxxxxbbbxx", "aaaxbbb"
# The following traffic does not match this regular expression:
#"bbbaaa", "aabbbxxaaa"
(?x)
.*aaa(?[my_var=1]) |
.*bbb(?[my_var==1 -> sid()])
Example of setting and checking a variable
# This regular expression matches when "login.php" is seen in the traffic
# stream before "user=admin" Situation Context, e.g. "HTTP Request URI"
(?x)
.*login\.php(?[login_page_seen=1]) |
.*user=admin(?[login_page_seen==1 -> sid()])
All the arithmetic operations that are available in SMC regular expressions are listed in the table below. Operator precedence is the same as in the C programming language, except that '->' is the lowest in precedence. Statements inside parentheses '()' are always evaluated first, so the order of operations can be overridden with parentheses.
Sequence | Description |
---|---|
false
|
Always evaluates to a false. |
true
|
Always evaluates to a true. |
<number>
|
A literal number in decimal, octal, and hexadecimal format, for example "32" or "0x20". |
<var> = <expr>
|
Sets a value returned by expression <expr> to a variable
<var> . See variable syntax below. |
<var> += <expr>
|
Adds the value of variable <var> with the value returned
by expression <expr> and sets the result to variable
<var> . |
<var> -= <expr>
|
Subtracts the value from variable <var> by the value
returned by expression <expr> and sets the result to variable
<var> . |
<var> *= <expr>
|
Multiplies the value of <var> by the value returned by
expression <expr> and sets the result to variable
<var> . |
<var> /= <expr>
|
Divides the value of <var> with the value returned by
expression <expr> and sets the result to variable
<var> . |
<var> %= <expr>
|
Divides the value of <var> with the value returned by
expression <expr> and sets the modulo of the result to variable
<var> . |
<var> <<= <expr>
|
Shifts the value of <var> to left by number of steps
returned by expression <expr> and sets the result to variable
<var> . |
<var> >>= <expr>
|
Shifts the value of <var> to right by number of steps
returned by expression <expr> and sets the result to variable
<var> . |
<var> &= <expr>
|
Performs bitwise AND with the value of variable <var> and
the value returned by expression <expr> and sets the result to variable
<var> . |
<var> |= <expr>
|
Performs bitwise OR with the value of variable <var> and
the value returned by expression <expr> and sets the result to variable
<var> . |
<var> ^= <expr>
|
Performs bitwise XOR with the value of variable <var> and
the value returned by expression <expr> and sets the result to variable
<var> . |
<expr_a> -> <expr_b>
|
Expression <expr b> is evaluated only if <expr
a> is true. |
<expr_a> ? <expr_b> : <expr_c>
|
Expression <expr b> is evaluated only if <expr
b> is true and expression <expr c> is evaluated if
<expr a> is false. |
<expr_a> == <expr_b>
|
Test if expressions <expr a> and <expr
b> return an equal value. |
<expr_a> != <expr_b>
|
Test if expressions <expr a> and <expr
b> do not return an equal value. |
<expr_a> < <expr_b>
|
Test if expression <expr b> returns higher value than
expression <expr a> . |
<expr_a> <= <expr_b>
|
Test if expression <expr b> returns higher or equal value
than expression <expr a> . |
<expr_a> > <expr_b>
|
Test if expression <expr a> returns higher value than
expression <expr b> . |
<expr_a> >= <expr_b>
|
Test if expression <expr a> returns higher or equal value
than expression <expr b> . |
<expr_a> & <expr_b>
|
Performs bitwise AND with expressions <expr_a> and <expr
b> and returns the result. |
<expr_a> | <expr_b>
|
Performs bitwise OR with expressions <expr a> and
<expr b> and returns the result. |
<expr_a> ^ <expr_b>
|
Performs bitwise XOR with expressions <expr a> and
<expr b> and returns the result. |
<expr_a> && <expr_b>
|
Performs AND with expressions <expr a> and
<expr b> and returns the result. |
<expr_a> || <expr_b>
|
Performs OR with if expressions <expr a> and
<expr b> and returns the result. |
<var>++, ++<var>
|
Increase value of variable <var> by one. |
<var>--, --<var>
|
Decrease value of variable <var> by one. |
-<expr>
|
Negate the result of the expression <expr> . |
~<expr>
|
Bitwise invert the result of the expression <expr> .
|
!<expr>
|
Perform NOT operation with the expression <expr> . |
.*aaa(?[var1=1])
”, the starting of the variable expression “(?[var1=1])
” is the most time-consuming operation, whereas setting or checking a variable value is a relatively fast operation. For example, the regular expression “.*/(?[parameter1=1])
” in an HTTP context would cause the starting of a variable expression after every “/” character in the traffic stream. As this character is common in HTTP protocol, the regular expression might degrade the system performance.