The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
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.
 
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.
 
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_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, ... }.
 
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.
 
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.
 
static const fr_type_t upcast_cmp [FR_TYPE_MAX+1][FR_TYPE_MAX+1]
 Updates type (a,b) -> c.
 
static const fr_type_t upcast_op [FR_TYPE_MAX+1][FR_TYPE_MAX+1]
 Updates type (a,b) -> c.
 
static const fr_type_t upcast_unsigned [FR_TYPE_MAX+1]
 

Detailed Description

Functions to perform calculations on leaf values.

Id
69fdca482b509f6bc5cd24ace25f6f075f1aeb96

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; \
fr_value_box_safety_copy(&_box, _vb); \
_vb = &_box; \
} \
} while (0)
while(1)
Definition acutest.h:856
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:3974
void fr_value_box_safety_copy(fr_value_box_t *out, fr_value_box_t const *in)
Copy the safety values from one box to another.
Definition value.c:7430

Definition at line 40 of file calc.c.

◆ COERCE_A

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

Definition at line 48 of file calc.c.

◆ COERCE_B

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

Definition at line 49 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 1650 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 2485 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 1944 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 728 of file calc.c.

◆ 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 1652 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 1664 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 776 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 1674 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 1724 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 1860 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 1296 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 1347 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 1500 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 1590 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 904 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 1079 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 819 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 1773 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 1231 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 1432 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 2506 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 1992 of file calc.c.

+ Here is the call 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 2733 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 2705 of file calc.c.

+ Here is the call graph for this function:
+ Here is the caller 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 2351 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 2567 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 1567 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 706 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 699 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:2485

Definition at line 2487 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 1949 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 427 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 66 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.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.

Definition at line 690 of file calc.c.