fr_value_box_memdup_shallow(dst, dst->enumv, buf, len, a->tainted | b->tainted);
break;
+ case T_AND:
+ if (a->vb_length != b->vb_length) {
+ length_error:
+ fr_strerror_const("Cannot perform operation on strings of different length");
+ return -1;
+ }
+
+ buf = talloc_array(ctx, uint8_t, a->vb_length);
+ if (!buf) goto oom;
+
+ for (len = 0; len < a->vb_length; len++) {
+ buf[len] = a->vb_octets[len] & b->vb_octets[len];
+ }
+
+ fr_value_box_clear_value(dst);
+ fr_value_box_memdup_shallow(dst, dst->enumv, buf, a->vb_length, a->tainted | b->tainted);
+ break;
+
+ case T_OR:
+ if (a->vb_length != b->vb_length) goto length_error;
+
+ buf = talloc_array(ctx, uint8_t, a->vb_length);
+ if (!buf) goto oom;
+
+ for (len = 0; len < a->vb_length; len++) {
+ buf[len] = a->vb_octets[len] | b->vb_octets[len];
+ }
+
+ fr_value_box_clear_value(dst);
+ fr_value_box_memdup_shallow(dst, dst->enumv, buf, a->vb_length, a->tainted | b->tainted);
+ break;
+
default:
return ERR_INVALID; /* invalid operator */
}
case T_DIV: \
dst->vb_ ## _t = in1->vb_ ## _t / in2->vb_ ## _t; \
break; \
+ \
+ case T_AND: \
+ dst->vb_ ## _t = in1->vb_ ## _t & in2->vb_ ## _t; \
+ break; \
+ \
+ case T_OR: \
+ dst->vb_ ## _t = in1->vb_ ## _t | in2->vb_ ## _t; \
+ break; \
\
default: \
return ERR_INVALID; \
case T_SUB:
case T_MUL:
case T_DIV:
+ case T_AND:
+ case T_OR:
case T_OP_PREPEND:
fr_assert(hint != FR_TYPE_NULL);
# Calculate various thingies.
#
+######################################################################
+#
+# integers
+#
calc uint8 255 + uint8 255 -> uint8
match Value overflows/underflows when calculating answer for uint8
calc int32 -1 + uint8 14 -> int16
match 13
+calc int8 0x7f & uint8 0x40 -> uint8
+match 64
+
#
# Intermediate values are too large for destination, but the
# resulting value can fit.
calc uint32 1000 - uint32 999 -> uint8
match 1
+# this can be cast
+calc string "1" < uint32 2 -> bool
+match yes
+
+# this can't
+calc string "stuff" < uint32 2 -> bool
+match Failed parsing string as type 'uint32'
+
+######################################################################
+#
+# strings
+#
# string append
calc string "a" . string "b" -> string
match ab
calc string "ab" - string "b" -> string
match a
+######################################################################
+#
+# octets
+#
# octets prepend
calc octets "a" ^ octets "b" -> octets
match 0x6261
calc octets "ab" - octets "b" -> octets
match 0x61
+calc octets "a" & octets "b" -> octets
+match 0x60
+
+calc octets "a" | octets "b" -> octets
+match 0x63
+
+# we can "fake out" structs by just appending stuff
+calc ipaddr 127.0.0.1 . ipaddr 127.0.0.2 -> octets
+match 0x7f0000017f000002
+######################################################################
+#
+# times and dates
+#
# time deltas
calc time_delta 1 + time_delta 2 -> time_delta
match 3
calc date "Jan 11 1970 00:00:00 UTC" < date "Jan 1 1970 00:00:00 UTC"
match no
-# we can "fake out" structs by just appending stuff
-calc ipaddr 127.0.0.1 . ipaddr 127.0.0.2 -> octets
-match 0x7f0000017f000002
-
-# this can be cast
-calc string "1" < uint32 2 -> bool
-match yes
-
-# this can't
-calc string "stuff" < uint32 2 -> bool
-match Failed parsing string as type 'uint32'
+######################################################################
+#
+# ip addresses and prefixes
+#
#
# make an IP out of a prefix and an offset
match 2test
count
-match 48
+match 54