= Comparisons

.Syntax
[source,unlang]
----
lhs OP rhs
----

The most common use-case for conditions is to perform comparisons.
The `lhs` and `rhs` of a conditional comparison can be
xref:attr.adoc[&Attribute-Name] or xref:type/index.adoc[data].  The
the `OP` is an operator, commonly `==` or `\<=`.  It is used to
control how the two other portions of the condition are compared.

== The Comparison Operators

The comparison operators are given below.

[options="header"]
|=====
| Operator | Description
| < | less than
| \<= | less than or equals
| == | equals
| != | not equals
| >= | greater than or equals
| >  | greater than
| xref:condition/regex.adoc[=~] | regular expression matches
| xref:condition/regex.adoc[!~] | regular expression does not match
|=====

The comparison operators perform _type-specific_ comparisons.  The
only exceptions are the xref:condition/regex.adoc[regular expression] operators,
which interpret the `lhs` as a printable string, and the `rhs` as a
regular expression.

== IP Address Comparisons

The type-specific comparisons operate as expected for most data types.
The only exception is data types that are IP addresses or IP address
prefixes.  For those data types, the comparisons are done via the
following rules:

* Any unqualified IP address is assumed to have a /32 prefix (IPv4)
  or a /128 prefix (IPv6).

* If the prefixes of the left and right sides are equal, then the comparisons
  are performed on the IP address portion.

* If the prefixes of the left and right sides are not equal, then the
  comparisons are performed as _set membership checks_.

The syntax allows conditions such as `192.0.2.1 < 192.0.2/24`.  This
condition will return `true`, as the IP address `192.0.2.1' is within
the network `192.0.2/24`.

== Casting

In some situations, it is useful to force the left side to be
interpreted as a particular data type.

[NOTE]
The data types used by the cast *must* be a type taken from the RADIUS
dictionaries, e.g., `ipaddr`, `integer`, etc.  These types are not the
same as the xref:type/index.adoc[data types] used in the
configuration files.

.Syntax
[source,unlang]
----
<cast>lhs OP rhs
----

The `cast` text can be any one of the standard RADIUS dictionary data
types, as with the following example:

.Example
[source,unlang]
----
<ipaddr>&Class == 127.0.0.1
----

In this example, the `Class` attribute is treated as if it was an IPv4
address and is compared to the address `127.0.0.1`

Casting is most useful when the left side of a comparison is a
dynamically expanded string.  The cast ensures that the comparison is
done in a type-safe manner, instead of performing a string comparison.

.Example
[source,unlang]
----
<integer>`/bin/echo 00` == 0
----

In this example, the string output of the `echo` program is interpreted as an
integer.  It is then compared to the right side via integer
comparisons.  Since the integer `00` is equivalent to the integer `0`,
the comparison will match.  If the comparison had been performed via
string equality checks, then the comparison would fail, because the
strings `00` and `0` are different.

// Copyright (C) 2020 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// Development of this documentation was sponsored by Network RADIUS SAS.
