The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Typedefs | Functions | Variables
calc.c File Reference

Functions to perform calculations on leaf values. More...

#include <freeradius-devel/util/strerror.h>
#include <freeradius-devel/util/regex.h>
#include <math.h>
#include "calc.h"
+ Include dependency graph for calc.c:

Go to the source code of this file.

Macros

#define COERCE(_vb, _box, _type, _enumv)
 
#define COERCE_A(_type, _enumv)   COERCE(a, one, _type, _enumv)
 
#define COERCE_B(_type, _enumv)   COERCE(b, two, _type, _enumv)
 
#define COMP(_type, _field)   case FR_TYPE_ ## _type: dst->vb_ ##_field = (_field ## _t) ~src->vb_ ##_field; break
 
#define ERR_INVALID   (-2)
 
#define ERR_OVERFLOW   (-3)
 
#define ERR_UNDERFLOW   (-4)
 
#define ERR_ZERO   (-5)
 
#define is_ipv6(_x)   (((_x)->type == FR_TYPE_IPV6_ADDR) || ((_x)->type == FR_TYPE_IPV6_PREFIX) || ((((_x)->type == FR_TYPE_COMBO_IP_ADDR) || ((_x)->type == FR_TYPE_COMBO_IP_PREFIX)) && ((_x)->vb_ip.af == AF_INET6)))
 
#define swap(_a, _b)   do { __typeof__ (_a) _tmp = _a; _a = _b; _b = _tmp; } while (0)
 
#define T(_x)   [T_OP_ ## _x ## _EQ] = T_ ## _x
 

Typedefs

typedef int(* fr_binary_op_t) (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 

Functions

static int calc_bool (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_combo_ip_addr (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_combo_ip_prefix (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_date (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_float32 (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_float64 (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_int64 (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_ipv4_addr (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_ipv4_prefix (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_ipv6_addr (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int calc_ipv6_prefix (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_octets (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_string (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_time_delta (UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 
static int calc_uint64 (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
 
static int cast_ipv4_addr (fr_value_box_t *out, fr_value_box_t const *in)
 
static int cast_ipv6_addr (fr_value_box_t *out, fr_value_box_t const *in)
 
int fr_value_calc_assignment_op (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
 Calculate DST OP SRC. More...
 
int fr_value_calc_binary_op (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
 Calculate DST = A OP B. More...
 
int fr_value_calc_list_cmp (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_list_t const *list1, fr_token_t op, fr_value_box_list_t const *list2)
 
static bool fr_value_calc_list_empty (fr_value_box_list_t const *list)
 
int fr_value_calc_list_op (TALLOC_CTX *ctx, fr_value_box_t *box, fr_token_t op, fr_value_box_list_t const *list)
 Apply a set of operations in order to create an output box. More...
 
int fr_value_calc_nary_op (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_token_t op, fr_value_box_t const *group)
 Calculate DST = OP { A, B, C, ... More...
 
int fr_value_calc_unary_op (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
 Calculate unary operations. More...
 
static int get_ipv6_prefix (uint8_t const *in)
 
static int handle_result (fr_type_t type, fr_token_t op, int rcode)
 
static int invalid_type (fr_type_t type)
 

Variables

static const fr_token_t assignment2op [T_TOKEN_LAST]
 
static const fr_binary_op_t calc_type [FR_TYPE_MAX+1]
 Map output type to its associated function. More...
 
static const fr_type_t upcast_cmp [FR_TYPE_MAX+1][FR_TYPE_MAX+1]
 Updates type (a,b) -> c. More...
 
static const fr_type_t upcast_op [FR_TYPE_MAX+1][FR_TYPE_MAX+1]
 Updates type (a,b) -> c. More...
 
static const fr_type_t upcast_unsigned [FR_TYPE_MAX+1]
 

Detailed Description

Functions to perform calculations on leaf values.

Id
efa54e8a18513b795641ff2f17231e946e3fce24

Definition in file calc.c.

Macro Definition Documentation

◆ COERCE

#define COERCE (   _vb,
  _box,
  _type,
  _enumv 
)
Value:
do { \
if (_vb->type != _type) { \
if (fr_value_box_cast(NULL, &_box, _type, _enumv, _vb) < 0) return -1; \
_vb = &_box; \
} \
} while (0)
while(1)
Definition: acutest.h:856
return
Definition: module.c:174
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
Definition: value.c:3352

Definition at line 40 of file calc.c.

◆ COERCE_A

#define COERCE_A (   _type,
  _enumv 
)    COERCE(a, one, _type, _enumv)

Definition at line 47 of file calc.c.

◆ COERCE_B

#define COERCE_B (   _type,
  _enumv 
)    COERCE(b, two, _type, _enumv)

Definition at line 48 of file calc.c.

◆ COMP

#define COMP (   _type,
  _field 
)    case FR_TYPE_ ## _type: dst->vb_ ##_field = (_field ## _t) ~src->vb_ ##_field; break

◆ ERR_INVALID

#define ERR_INVALID   (-2)

Definition at line 38 of file calc.c.

◆ ERR_OVERFLOW

#define ERR_OVERFLOW   (-3)

Definition at line 37 of file calc.c.

◆ ERR_UNDERFLOW

#define ERR_UNDERFLOW   (-4)

Definition at line 36 of file calc.c.

◆ ERR_ZERO

#define ERR_ZERO   (-5)

Definition at line 35 of file calc.c.

◆ is_ipv6

#define is_ipv6 (   _x)    (((_x)->type == FR_TYPE_IPV6_ADDR) || ((_x)->type == FR_TYPE_IPV6_PREFIX) || ((((_x)->type == FR_TYPE_COMBO_IP_ADDR) || ((_x)->type == FR_TYPE_COMBO_IP_PREFIX)) && ((_x)->vb_ip.af == AF_INET6)))

Definition at line 1563 of file calc.c.

◆ swap

#define swap (   _a,
  _b 
)    do { __typeof__ (_a) _tmp = _a; _a = _b; _b = _tmp; } while (0)

Definition at line 33 of file calc.c.

◆ T

#define T (   _x)    [T_OP_ ## _x ## _EQ] = T_ ## _x

Definition at line 2378 of file calc.c.

Typedef Documentation

◆ fr_binary_op_t

typedef int(* fr_binary_op_t) (TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)

Definition at line 1846 of file calc.c.

Function Documentation

◆ calc_bool()

static int calc_bool ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 727 of file calc.c.

+ Here is the call graph for this function:

◆ calc_combo_ip_addr()

static int calc_combo_ip_addr ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1565 of file calc.c.

+ Here is the call graph for this function:

◆ calc_combo_ip_prefix()

static int calc_combo_ip_prefix ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1577 of file calc.c.

+ Here is the call graph for this function:

◆ calc_date()

static int calc_date ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 775 of file calc.c.

+ Here is the call graph for this function:

◆ calc_float32()

static int calc_float32 ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1587 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_float64()

static int calc_float64 ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1634 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_int64()

static int calc_int64 ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1765 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_ipv4_addr()

static int calc_ipv4_addr ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1220 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_ipv4_prefix()

static int calc_ipv4_prefix ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 1269 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_ipv6_addr()

static int calc_ipv6_addr ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1418 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_ipv6_prefix()

static int calc_ipv6_prefix ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 1505 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_octets()

static int calc_octets ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 903 of file calc.c.

+ Here is the call graph for this function:

◆ calc_string()

static int calc_string ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 1042 of file calc.c.

+ Here is the call graph for this function:

◆ calc_time_delta()

static int calc_time_delta ( UNUSED TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)
static

Definition at line 818 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_uint64()

static int calc_uint64 ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_t const *  in1,
fr_token_t  op,
fr_value_box_t const *  in2 
)
static

Definition at line 1681 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cast_ipv4_addr()

static int cast_ipv4_addr ( fr_value_box_t out,
fr_value_box_t const *  in 
)
static

Definition at line 1155 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cast_ipv6_addr()

static int cast_ipv6_addr ( fr_value_box_t out,
fr_value_box_t const *  in 
)
static

Definition at line 1352 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_value_calc_assignment_op()

int fr_value_calc_assignment_op ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_token_t  op,
fr_value_box_t const *  src 
)

Calculate DST OP SRC.

e.g. "foo += bar".

This is done by doing some sanity checks, and then just calling the "binary operation" function.

Definition at line 2399 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_value_calc_binary_op()

int fr_value_calc_binary_op ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_type_t  hint,
fr_value_box_t const *  a,
fr_token_t  op,
fr_value_box_t const *  b 
)

Calculate DST = A OP B.

The result is written to DST only after it has been calculated. So it's safe to pass DST as either A or B. DST should already exist.

This function should arguably not take comparison operators, but whatever. The "promote types" code is the same for all of the binary operations, so we might as well just have one function.

Definition at line 1894 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_value_calc_list_cmp()

int fr_value_calc_list_cmp ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_value_box_list_t const *  list1,
fr_token_t  op,
fr_value_box_list_t const *  list2 
)

Definition at line 2688 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_value_calc_list_empty()

static bool fr_value_calc_list_empty ( fr_value_box_list_t const *  list)
static

Definition at line 2660 of file calc.c.

+ Here is the caller graph for this function:

◆ fr_value_calc_list_op()

int fr_value_calc_list_op ( TALLOC_CTX *  ctx,
fr_value_box_t box,
fr_token_t  op,
fr_value_box_list_t const *  list 
)

Apply a set of operations in order to create an output box.

Definition at line 2588 of file calc.c.

+ Here is the call graph for this function:

◆ fr_value_calc_nary_op()

int fr_value_calc_nary_op ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_type_t  type,
fr_token_t  op,
fr_value_box_t const *  group 
)

Calculate DST = OP { A, B, C, ...

}

The result is written to DST only after it has been calculated. So it's safe to pass DST as one of the inputs. DST should already exist.

Definition at line 2239 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_value_calc_unary_op()

int fr_value_calc_unary_op ( TALLOC_CTX *  ctx,
fr_value_box_t dst,
fr_token_t  op,
fr_value_box_t const *  src 
)

Calculate unary operations.

e.g. "foo++", or "-foo".

Definition at line 2460 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_ipv6_prefix()

static int get_ipv6_prefix ( uint8_t const *  in)
static

Definition at line 1482 of file calc.c.

+ Here is the caller graph for this function:

◆ handle_result()

static int handle_result ( fr_type_t  type,
fr_token_t  op,
int  rcode 
)
static

Definition at line 705 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ invalid_type()

static int invalid_type ( fr_type_t  type)
static

Definition at line 698 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ assignment2op

const fr_token_t assignment2op[T_TOKEN_LAST]
static
Initial value:
= {
T(ADD),
T(SUB),
T(MUL),
T(DIV),
T(AND),
T(OR),
T(XOR),
T(RSHIFT),
T(LSHIFT),
}
#define T(_x)
Definition: calc.c:2378

Definition at line 2380 of file calc.c.

◆ calc_type

const fr_binary_op_t calc_type[FR_TYPE_MAX+1]
static

Map output type to its associated function.

Definition at line 1851 of file calc.c.

◆ upcast_cmp

const fr_type_t upcast_cmp[FR_TYPE_MAX+1][FR_TYPE_MAX+1]
static

Updates type (a,b) -> c.

Note that we MUST have a less than b here. Otherwise there will be two entries for the same upcast, and the entries may get out of sync.

These upcasts are for comparisons. In some cases, we can promote one data type to another, and then compare them. However, this is not always possible.

If one side is a string and the other isn't, then we try to parse the string as the type of the other side.

If one side is an octets type and the other isn't, then we try to parse the octets as the type of the other side.

Todo:

Definition at line 426 of file calc.c.

◆ upcast_op

const fr_type_t upcast_op[FR_TYPE_MAX+1][FR_TYPE_MAX+1]
static

Updates type (a,b) -> c.

Note that we MUST have a less than b here. Otherwise there will be two entries for the same upcast, and the entries may get out of sync.

These upcasts are for operations.

If one side is a string and the other isn't, then we try to parse the string as the type of the other side.

If one side is an octets type and the other isn't, then we try to parse the octets as the type of the other side.

Definition at line 65 of file calc.c.

◆ upcast_unsigned

const fr_type_t upcast_unsigned[FR_TYPE_MAX+1]
static
Initial value:
= {
}
@ FR_TYPE_INT8
8 Bit signed integer.
Definition: merged_model.c:103
@ FR_TYPE_UINT16
16 Bit unsigned integer.
Definition: merged_model.c:98
@ FR_TYPE_INT64
64 Bit signed integer.
Definition: merged_model.c:106
@ FR_TYPE_INT16
16 Bit signed integer.
Definition: merged_model.c:104
@ FR_TYPE_UINT8
8 Bit unsigned integer.
Definition: merged_model.c:97
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_INT32
32 Bit signed integer.
Definition: merged_model.c:105
@ FR_TYPE_UINT64
64 Bit unsigned integer.
Definition: merged_model.c:100
@ FR_TYPE_BOOL
A truth value.
Definition: merged_model.c:95
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
Definition: merged_model.c:115

Definition at line 689 of file calc.c.