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)
 
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
2730e4dfaf3fa93d336c2c18132e3171b7d0762e

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:186
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:3301

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 1562 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 2366 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 1845 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 1564 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 1576 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 1586 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 1633 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 1764 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 1417 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 1504 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 1680 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 1351 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 2387 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 1893 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 2645 of file calc.c.

+ Here is the call graph for this function:
+ 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 2576 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 2228 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 2448 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 1481 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:2366

Definition at line 2368 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 1850 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.