From: Arran Cudbard-Bell Date: Mon, 15 May 2017 22:32:37 +0000 (-0400) Subject: Add support for Diameter and IPFIX base types X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cd596f2cea9f2f3afdb1a7f0b706519bbc8ad3b2;p=thirdparty%2Ffreeradius-server.git Add support for Diameter and IPFIX base types --- diff --git a/src/include/libradius.h b/src/include/libradius.h index 8a45cc22727..56a26a62655 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -159,7 +159,8 @@ int rad_unlockfd(int fd, int lock_len); char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen); size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen); size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen); -uint32_t fr_strtoul(char const *value, char **end); +uint64_t fr_strtoull(char const *value, char **end); +int64_t fr_strtoll(char const *value, char **end); bool is_whitespace(char const *value); bool is_printable(void const *value, size_t len); bool is_integer(char const *value); diff --git a/src/include/pair.h b/src/include/pair.h index 7b7cc20d89b..66b956fcf60 100644 --- a/src/include/pair.h +++ b/src/include/pair.h @@ -124,32 +124,41 @@ typedef struct value_pair_raw { FR_TOKEN op; //!< Operator. } VALUE_PAIR_RAW; -#define vp_strvalue data.datum.strvalue -#define vp_octets data.datum.octets -#define vp_ptr data.datum.ptr //!< Either octets or strvalue -#define vp_length data.datum.length - -#define vp_ipv4addr data.datum.ip.addr.v4.s_addr -#define vp_ipv6addr data.datum.ip.addr.v6.s6_addr -#define vp_ip data.datum.ip -#define vp_ifid data.datum.ifid -#define vp_ether data.datum.ether - -#define vp_bool data.datum.boolean -#define vp_uint8 data.datum.uint8 -#define vp_short data.datum.uint16 -#define vp_uint32 data.datum.uint32 -#define vp_uint64 data.datum.uint64 -#define vp_size data.datum.size - -#define vp_signed data.datum.int32 -#define vp_float64 data.datum.float64 - -#define vp_date data.datum.date -#define vp_filter data.datum.filter - -#define vp_type data.type -#define vp_tainted data.tainted +#define vp_strvalue data.datum.strvalue +#define vp_octets data.datum.octets +#define vp_ptr data.datum.ptr //!< Either octets or strvalue +#define vp_length data.datum.length + +#define vp_ipv4addr data.datum.ip.addr.v4.s_addr +#define vp_ipv6addr data.datum.ip.addr.v6.s6_addr +#define vp_ip data.datum.ip +#define vp_ifid data.datum.ifid +#define vp_ether data.datum.ether + +#define vp_bool data.datum.boolean +#define vp_uint8 data.datum.uint8 +#define vp_uint16 data.datum.uint16 +#define vp_uint32 data.datum.uint32 +#define vp_uint64 data.datum.uint64 + +#define vp_int8 data.datum.int8 +#define vp_int16 data.datum.int16 +#define vp_int32 data.datum.int32 +#define vp_int64 data.datum.int64 + +#define vp_float32 data.datum.float32 +#define vp_float64 data.datum.float64 + +#define vp_date data.datum.date +#define vp_date_milliseconds data.datum.date_milliseconds +#define vp_date_microseconds data.datum.date_microseconds +#define vp_date_nanoseconds data.datum.date_nanoseconds + +#define vp_size data.datum.size +#define vp_filter data.datum.filter + +#define vp_type data.type +#define vp_tainted data.tainted # define debug_pair(vp) do { if (fr_debug_lvl && fr_log_fp) { \ fr_pair_fprint(fr_log_fp, vp); \ diff --git a/src/include/types.h b/src/include/types.h index 8f434102344..8316c9908a3 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -44,18 +44,29 @@ typedef enum { FR_TYPE_ETHERNET, //!< 48 Bit Mac-Address. FR_TYPE_BOOL, //!< A truth value. + FR_TYPE_UINT8, //!< 8 Bit unsigned integer. FR_TYPE_UINT16, //!< 16 Bit unsigned integer. FR_TYPE_UINT32, //!< 32 Bit unsigned integer. FR_TYPE_UINT64, //!< 64 Bit unsigned integer. + + FR_TYPE_INT8, //!< 8 Bit signed integer. + FR_TYPE_INT16, //!< 16 Bit signed integer. FR_TYPE_INT32, //!< 32 Bit signed integer. + FR_TYPE_INT64, //!< 64 Bit signed integer. + + FR_TYPE_FLOAT32, //!< Single precision floating point. FR_TYPE_FLOAT64, //!< Double precision floating point. + FR_TYPE_DATE, //!< 32 Bit Unix timestamp. + FR_TYPE_DATE_MILLISECONDS, //!< Milliseconds since the epoch. + FR_TYPE_DATE_MICROSECONDS, //!< Microseconds since the epoch. + FR_TYPE_DATE_NANOSECONDS, //!< Nanoseconds since the epoch. + FR_TYPE_SIZE, //!< Unsigned integer capable of representing any memory //!< address on the local system. FR_TYPE_TIMEVAL, //!< Time value (struct timeval), only for config items. - FR_TYPE_DATE, //!< 32 Bit Unix timestamp. FR_TYPE_ABINARY, //!< Ascend binary format a packed data structure. @@ -134,6 +145,15 @@ typedef enum { case FR_TYPE_VSA: \ case FR_TYPE_VENDOR +/** Types which do not represent concrete values + * + */ +#define FR_TYPE_NOT_VALUES \ + FR_TYPE_COMBO_IP_ADDR: \ + case FR_TYPE_COMBO_IP_PREFIX: \ + case FR_TYPE_STRUCTURAL: \ + case FR_TYPE_BAD + /** Naturally numeric types * */ @@ -143,8 +163,16 @@ typedef enum { case FR_TYPE_UINT16: \ case FR_TYPE_UINT32: \ case FR_TYPE_UINT64: \ - case FR_TYPE_SIZE: \ + case FR_TYPE_INT8: \ + case FR_TYPE_INT16: \ case FR_TYPE_INT32: \ - case FR_TYPE_DATE + case FR_TYPE_INT64: \ + case FR_TYPE_FLOAT32: \ + case FR_TYPE_FLOAT64: \ + case FR_TYPE_DATE: \ + case FR_TYPE_DATE_MILLISECONDS: \ + case FR_TYPE_DATE_MICROSECONDS: \ + case FR_TYPE_DATE_NANOSECONDS: \ + case FR_TYPE_SIZE #endif /* _FR_TYPES_H */ diff --git a/src/include/value.h b/src/include/value.h index c461a955d0d..d901ab32a4b 100644 --- a/src/include/value.h +++ b/src/include/value.h @@ -78,9 +78,10 @@ struct value_box { double float64; //!< Double precision float. uint32_t date; //!< Date (32bit Unix timestamp). - uint64_t date_miliseconds; //!< Milliseconds since the epoch. - uint64_t date_microseconds; //!< Microseconds since the epoch. - uint64_t date_nanoseconds; //!< Nanoseconds since the epoch. + + uint64_t date_milliseconds; //!< milliseconds since the epoch. + uint64_t date_microseconds; //!< microseconds since the epoch. + uint64_t date_nanoseconds; //!< nanoseconds since the epoch. /* * System specific - Used for runtime configuration only. @@ -138,7 +139,7 @@ struct value_box { #define fr_box_float64(_val) _fr_box(FR_TYPE_FLOAT64, .datum.float64, _val) #define fr_box_date(_val) _fr_box(FR_TYPE_DATE, date, _val) -#define fr_box_date_miliseconds(_val) _fr_box(FR_TYPE_DATE_MILISECONDS, date_miliseconds, _val) +#define fr_box_date_milliseconds(_val) _fr_box(FR_TYPE_DATE_MILISECONDS, date_milliseconds, _val) #define fr_box_date_microseconds(_val) _fr_box(FR_TYPE_DATE_MICROSECONDS, date_microseconds, _val) #define fr_box_date_nanoseconds(_val) _fr_box(FR_TYPE_DATE_NANOSECONDS, date_nanoseconds, _val) @@ -174,7 +175,7 @@ struct value_box { #define fr_unbox_float64(_box) _box->datum.float64 #define fr_unbox_date(_val) _box->datum.date -#define fr_unbox_date_miliseconds(_val) _box->datum.date_miliseconds +#define fr_unbox_date_milliseconds(_val) _box->datum.date_milliseconds #define fr_unbox_date_microseconds(_val) _box->datum.date_microseconds #define fr_unbox_date_nanoseconds(_val) _box->datum.date_nanoseconds diff --git a/src/lib/util/dict.c b/src/lib/util/dict.c index b2cf452b561..26d7f254a56 100644 --- a/src/lib/util/dict.c +++ b/src/lib/util/dict.c @@ -116,17 +116,25 @@ FR_NAME_NUMBER const dict_attr_types[] = { { "uint16", FR_TYPE_UINT16 }, { "uint32", FR_TYPE_UINT32 }, { "uint64", FR_TYPE_UINT64 }, + + { "int8", FR_TYPE_INT8 }, + { "int16", FR_TYPE_INT16 }, { "int32", FR_TYPE_INT32 }, + { "int64", FR_TYPE_INT64 }, - { "size", FR_TYPE_SIZE }, - { "signed", FR_TYPE_INT32 }, + { "float32", FR_TYPE_FLOAT32 }, + { "float64", FR_TYPE_FLOAT64 }, - { "decimal", FR_TYPE_FLOAT64 }, { "timeval", FR_TYPE_TIMEVAL }, { "date", FR_TYPE_DATE }, + { "date_milliseconds", FR_TYPE_DATE_MILLISECONDS }, + { "date_microseconds", FR_TYPE_DATE_MICROSECONDS }, + { "date_nanoseconds", FR_TYPE_DATE_NANOSECONDS }, { "abinary", FR_TYPE_ABINARY }, + { "size", FR_TYPE_SIZE }, + { "tlv", FR_TYPE_TLV }, { "struct", FR_TYPE_STRUCT }, @@ -145,6 +153,8 @@ FR_NAME_NUMBER const dict_attr_types[] = { { "short", FR_TYPE_UINT16 }, { "integer", FR_TYPE_UINT32 }, { "integer64", FR_TYPE_UINT64 }, + { "decimal", FR_TYPE_FLOAT64 }, + { "signed", FR_TYPE_INT32 }, { NULL, 0 } }; diff --git a/src/lib/util/misc.c b/src/lib/util/misc.c index 1759e6c0a1a..eb8c8daa0c2 100644 --- a/src/lib/util/misc.c +++ b/src/lib/util/misc.c @@ -333,17 +333,38 @@ char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen) /** Consume the integer (or hex) portion of a value string * - * @param value string to parse. - * @param end pointer to the first non numeric char. + * Allows integer or hex representations of integers (but not octal, + * as octal is deemed to be confusing). + * + * @param[in] value string to parse. + * @param[out] end pointer to the first non numeric char. + * @return integer value. + */ +uint64_t fr_strtoull(char const *value, char **end) +{ + if ((value[0] == '0') && (value[1] == 'x')) { + return strtoull(value, end, 16); + } + + return strtoull(value, end, 10); +} + +/** Consume the integer (or hex) portion of a value string + * + * Allows integer or hex representations of integers (but not octal, + * as octal is deemed to be confusing). + * + * @param[in] value string to parse. + * @param[out] end pointer to the first non numeric char. * @return integer value. */ -uint32_t fr_strtoul(char const *value, char **end) +int64_t fr_strtoll(char const *value, char **end) { if ((value[0] == '0') && (value[1] == 'x')) { - return strtoul(value, end, 16); + return strtoll(value, end, 16); } - return strtoul(value, end, 10); + return strtoll(value, end, 10); } /** Check whether the string is all whitespace diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 79959c44acf..434a7efad50 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -2266,15 +2266,8 @@ char const *fr_pair_value_enum(VALUE_PAIR const *vp, char buff[20]) case FR_TYPE_BOOL: return vp->vp_bool ? "yes" : "no"; - case FR_TYPE_UINT8: - case FR_TYPE_UINT16: - case FR_TYPE_UINT32: - case FR_TYPE_UINT64: - case FR_TYPE_INT32: - enumv = fr_dict_enum_by_value(NULL, vp->da, &vp->data); - break; - default: + enumv = fr_dict_enum_by_value(NULL, vp->da, &vp->data); break; } diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 295fdbef56a..5dc8e58959c 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -60,30 +60,39 @@ RCSID("$Id$") * length attributes too. */ static size_t const fr_value_box_network_sizes[FR_TYPE_MAX + 1][2] = { - [FR_TYPE_INVALID] = {~0, 0}, + [FR_TYPE_INVALID] = {~0, 0}, - [FR_TYPE_STRING] = {0, ~0}, - [FR_TYPE_OCTETS] = {0, ~0}, + [FR_TYPE_STRING] = {0, ~0}, + [FR_TYPE_OCTETS] = {0, ~0}, - [FR_TYPE_IPV4_ADDR] = {4, 4}, - [FR_TYPE_IPV4_PREFIX] = {6, 6}, - [FR_TYPE_IPV6_ADDR] = {16, 16}, - [FR_TYPE_IPV6_PREFIX] = {18, 18}, - [FR_TYPE_IFID] = {8, 8}, - [FR_TYPE_ETHERNET] = {6, 6}, + [FR_TYPE_IPV4_ADDR] = {4, 4}, + [FR_TYPE_IPV4_PREFIX] = {6, 6}, + [FR_TYPE_IPV6_ADDR] = {16, 16}, + [FR_TYPE_IPV6_PREFIX] = {18, 18}, + [FR_TYPE_IFID] = {8, 8}, + [FR_TYPE_ETHERNET] = {6, 6}, - [FR_TYPE_BOOL] = {1, 1}, - [FR_TYPE_UINT8] = {1, 1}, + [FR_TYPE_BOOL] = {1, 1}, + [FR_TYPE_UINT8] = {1, 1}, [FR_TYPE_UINT16] = {2, 2}, - [FR_TYPE_UINT32] = {4, 4}, - [FR_TYPE_UINT64] = {8, 8}, + [FR_TYPE_UINT32] = {4, 4}, + [FR_TYPE_UINT64] = {8, 8}, - [FR_TYPE_INT32] = {4, 4}, + [FR_TYPE_INT8] = {1, 1}, + [FR_TYPE_INT16] = {2, 2}, + [FR_TYPE_INT32] = {4, 4}, + [FR_TYPE_INT64] = {8, 8}, - [FR_TYPE_DATE] = {4, 4}, //!< 64bit on most machines. + [FR_TYPE_FLOAT32] = {4, 4}, + [FR_TYPE_FLOAT64] = {8, 8}, - [FR_TYPE_ABINARY] = {32, ~0}, - [FR_TYPE_MAX] = {~0, 0} //!< Ensure array covers all types. + [FR_TYPE_DATE] = {4, 4}, + [FR_TYPE_DATE_MILLISECONDS] = {8, 8}, + [FR_TYPE_DATE_MICROSECONDS] = {8, 8}, + [FR_TYPE_DATE_NANOSECONDS] = {8, 8}, + + [FR_TYPE_ABINARY] = {32, ~0}, + [FR_TYPE_MAX] = {~0, 0} //!< Ensure array covers all types. }; static_assert(SIZEOF_MEMBER(fr_value_box_t, datum.ip.addr.v4.s_addr) == 4, @@ -129,13 +138,22 @@ size_t const fr_value_box_field_sizes[] = { [FR_TYPE_UINT16] = SIZEOF_MEMBER(fr_value_box_t, datum.uint16), [FR_TYPE_UINT32] = SIZEOF_MEMBER(fr_value_box_t, datum.uint32), [FR_TYPE_UINT64] = SIZEOF_MEMBER(fr_value_box_t, datum.uint64), - [FR_TYPE_SIZE] = SIZEOF_MEMBER(fr_value_box_t, datum.size), + [FR_TYPE_INT8] = SIZEOF_MEMBER(fr_value_box_t, datum.int8), + [FR_TYPE_INT16] = SIZEOF_MEMBER(fr_value_box_t, datum.int16), [FR_TYPE_INT32] = SIZEOF_MEMBER(fr_value_box_t, datum.int32), + [FR_TYPE_INT64] = SIZEOF_MEMBER(fr_value_box_t, datum.int64), - [FR_TYPE_TIMEVAL] = SIZEOF_MEMBER(fr_value_box_t, datum.timeval), + [FR_TYPE_FLOAT32] = SIZEOF_MEMBER(fr_value_box_t, datum.float32), [FR_TYPE_FLOAT64] = SIZEOF_MEMBER(fr_value_box_t, datum.float64), + [FR_TYPE_DATE] = SIZEOF_MEMBER(fr_value_box_t, datum.date), + [FR_TYPE_DATE_MILLISECONDS] = SIZEOF_MEMBER(fr_value_box_t, datum.date_milliseconds), + [FR_TYPE_DATE_MICROSECONDS] = SIZEOF_MEMBER(fr_value_box_t, datum.date_microseconds), + [FR_TYPE_DATE_NANOSECONDS] = SIZEOF_MEMBER(fr_value_box_t, datum.date_nanoseconds), + + [FR_TYPE_TIMEVAL] = SIZEOF_MEMBER(fr_value_box_t, datum.timeval), + [FR_TYPE_SIZE] = SIZEOF_MEMBER(fr_value_box_t, datum.size), [FR_TYPE_ABINARY] = SIZEOF_MEMBER(fr_value_box_t, datum.filter), [FR_TYPE_MAX] = 0 //!< Ensure array covers all types. @@ -160,14 +178,22 @@ size_t const fr_value_box_offsets[] = { [FR_TYPE_UINT16] = offsetof(fr_value_box_t, datum.uint16), [FR_TYPE_UINT32] = offsetof(fr_value_box_t, datum.uint32), [FR_TYPE_UINT64] = offsetof(fr_value_box_t, datum.uint64), - [FR_TYPE_SIZE] = offsetof(fr_value_box_t, datum.size), + [FR_TYPE_INT8] = offsetof(fr_value_box_t, datum.int8), + [FR_TYPE_INT16] = offsetof(fr_value_box_t, datum.int16), [FR_TYPE_INT32] = offsetof(fr_value_box_t, datum.int32), + [FR_TYPE_INT64] = offsetof(fr_value_box_t, datum.int64), - [FR_TYPE_TIMEVAL] = offsetof(fr_value_box_t, datum.timeval), + [FR_TYPE_FLOAT32] = offsetof(fr_value_box_t, datum.float32), [FR_TYPE_FLOAT64] = offsetof(fr_value_box_t, datum.float64), [FR_TYPE_DATE] = offsetof(fr_value_box_t, datum.date), + [FR_TYPE_DATE_MILLISECONDS] = offsetof(fr_value_box_t, datum.date_milliseconds), + [FR_TYPE_DATE_MICROSECONDS] = offsetof(fr_value_box_t, datum.date_microseconds), + [FR_TYPE_DATE_NANOSECONDS] = offsetof(fr_value_box_t, datum.date_nanoseconds), + + [FR_TYPE_TIMEVAL] = offsetof(fr_value_box_t, datum.timeval), + [FR_TYPE_SIZE] = offsetof(fr_value_box_t, datum.size), [FR_TYPE_ABINARY] = offsetof(fr_value_box_t, datum.filter), [FR_TYPE_MAX] = 0 //!< Ensure array covers all types. @@ -305,6 +331,11 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) } else if (a->datum._type > b->datum._type) { compare = +1; } case FR_TYPE_BOOL: /* this isn't a RADIUS type, and shouldn't really ever be used */ + + case FR_TYPE_DATE: + CHECK(date); + break; + case FR_TYPE_UINT8: CHECK(uint8); break; @@ -313,20 +344,28 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) CHECK(uint16); break; - case FR_TYPE_DATE: - CHECK(date); - break; - case FR_TYPE_UINT32: CHECK(int32); break; + case FR_TYPE_UINT64: + CHECK(uint64); + break; + + case FR_TYPE_INT8: + CHECK(int8); + break; + + case FR_TYPE_INT16: + CHECK(int16); + break; + case FR_TYPE_INT32: CHECK(int32); break; - case FR_TYPE_UINT64: - CHECK(uint64); + case FR_TYPE_INT64: + CHECK(int64); break; case FR_TYPE_SIZE: @@ -337,10 +376,26 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) compare = fr_timeval_cmp(&a->datum.timeval, &b->datum.timeval); break; + case FR_TYPE_FLOAT32: + CHECK(float32); + break; + case FR_TYPE_FLOAT64: CHECK(float64); break; + case FR_TYPE_DATE_MILLISECONDS: + CHECK(date_milliseconds); + break; + + case FR_TYPE_DATE_MICROSECONDS: + CHECK(date_microseconds); + break; + + case FR_TYPE_DATE_NANOSECONDS: + CHECK(date_nanoseconds); + break; + case FR_TYPE_ETHERNET: compare = memcmp(a->datum.ether, b->datum.ether, sizeof(a->datum.ether)); break; @@ -800,25 +855,49 @@ int fr_value_box_hton(fr_value_box_t *dst, fr_value_box_t const *src) { if (!fr_cond_assert(src->type != FR_TYPE_INVALID)) return -1; - /* 8 uint8 uint32s */ + switch (src->type) { - case FR_TYPE_UINT64: - dst->datum.uint64 = htonll(src->datum.uint64); - fr_value_box_copy_meta(dst, src); + /* 2 uint8 uint32s */ + case FR_TYPE_UINT16: + dst->datum.uint16 = htons(src->datum.uint16); break; /* 4 uint8 uint32s */ case FR_TYPE_UINT32: - case FR_TYPE_DATE: - case FR_TYPE_INT32: dst->datum.uint32 = htonl(src->datum.uint32); - fr_value_box_copy_meta(dst, src); break; - /* 2 uint8 uint32s */ - case FR_TYPE_UINT16: - dst->datum.uint16 = htons(src->datum.uint16); - fr_value_box_copy_meta(dst, src); + /* 8 uint8 uint32s */ + case FR_TYPE_UINT64: + dst->datum.uint64 = htonll(src->datum.uint64); + break; + + case FR_TYPE_INT16: + dst->datum.int16 = htons((uint16_t) src->datum.int16); + break; + + case FR_TYPE_INT32: + dst->datum.int32 = htonl((uint32_t) src->datum.int32); + break; + + case FR_TYPE_INT64: + dst->datum.int64 = htonll((uint64_t) src->datum.int64); + break; + + case FR_TYPE_DATE: + dst->datum.date = htonl(src->datum.date); + break; + + case FR_TYPE_DATE_MILLISECONDS: + dst->datum.date_milliseconds = htonll(src->datum.date_milliseconds); + break; + + case FR_TYPE_DATE_MICROSECONDS: + dst->datum.date_microseconds = htonll(src->datum.date_microseconds); + break; + + case FR_TYPE_DATE_NANOSECONDS: + dst->datum.date_nanoseconds = htonll(src->datum.date_nanoseconds); break; case FR_TYPE_OCTETS: @@ -827,9 +906,11 @@ int fr_value_box_hton(fr_value_box_t *dst, fr_value_box_t const *src) default: fr_value_box_copy(NULL, dst, src); - break; + return 0; } + fr_value_box_copy_meta(dst, src); + return 0; } @@ -1423,11 +1504,19 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, case FR_TYPE_UINT16: case FR_TYPE_UINT32: case FR_TYPE_UINT64: - case FR_TYPE_SIZE: + case FR_TYPE_INT8: + case FR_TYPE_INT16: case FR_TYPE_INT32: - case FR_TYPE_TIMEVAL: + case FR_TYPE_INT64: + case FR_TYPE_FLOAT32: case FR_TYPE_FLOAT64: case FR_TYPE_DATE: + case FR_TYPE_DATE_MILLISECONDS: + case FR_TYPE_DATE_MICROSECONDS: + case FR_TYPE_DATE_NANOSECONDS: + + case FR_TYPE_SIZE: + case FR_TYPE_TIMEVAL: case FR_TYPE_ABINARY: break; @@ -2201,6 +2290,138 @@ int fr_value_box_from_ipaddr(fr_value_box_t *dst, fr_ipaddr_t const *ipaddr) return 0; } +/** Convert integer encoded as string to a fr_value_box_t type + * + * @param[out] dst where to write parsed value. + * @param[in] dst_type type of integer to convert string to. + * @param[in] in String to convert to integer. + * @return + * - 0 on success. + * - -1 on parse error. + */ +static int fr_value_box_integer_str(fr_value_box_t *dst, fr_type_t dst_type, char const *in) +{ + uint64_t uinteger; + int64_t sinteger; + char *p = NULL; + + switch (dst_type) { + case FR_TYPE_UINT8: + case FR_TYPE_UINT16: + case FR_TYPE_UINT32: + case FR_TYPE_UINT64: + case FR_TYPE_DATE_MILLISECONDS: + case FR_TYPE_DATE_MICROSECONDS: + case FR_TYPE_DATE_NANOSECONDS: + uinteger = fr_strtoll(in, &p); + if (*p != '\0') { + fr_strerror_printf("Invalid integer value \"%s\"", in); + + return -1; + } + break; + + case FR_TYPE_INT8: + case FR_TYPE_INT16: + case FR_TYPE_INT32: + case FR_TYPE_INT64: + sinteger = fr_strtoll(in, &p); + if (*p != '\0') { + fr_strerror_printf("Invalid integer value \"%s\"", in); + + return -1; + } + break; + + default: + if (!fr_cond_assert(0)) return -1; + } + +#define IN_RANGE_UNSIGNED(_type) \ + do { \ + if (uinteger > _type ## _MAX) { \ + fr_strerror_printf("Value %" PRIu64 " is invalid for type %s (must be in range " \ + "0-%" PRIu64 ")", \ + uinteger, fr_int2str(dict_attr_types, dst_type, ""), \ + (uint64_t) _type ## _MAX); \ + return -1; \ + } \ + } while (0) + +#define IN_RANGE_SIGNED(_type) \ + do { \ + if ((sinteger > _type ## _MAX) || (sinteger < _type ## _MIN)) { \ + fr_strerror_printf("Value %" PRIu64 " is invalid for type %s (must be in range " \ + "%" PRIu64 "-%" PRIu64 ")", \ + sinteger, fr_int2str(dict_attr_types, dst_type, ""), \ + (int64_t) _type ## _MIN, (int64_t) _type ## _MAX); \ + return -1; \ + } \ + } while (0) + + switch (dst_type) { + case FR_TYPE_UINT8: + IN_RANGE_UNSIGNED(UINT8); + dst->datum.uint8 = (uint8_t)uinteger; + break; + + case FR_TYPE_UINT16: + IN_RANGE_UNSIGNED(UINT16); + dst->datum.uint16 = (uint16_t)uinteger; + break; + + case FR_TYPE_UINT32: + IN_RANGE_UNSIGNED(UINT32); + dst->datum.uint32 = (uint32_t)uinteger; + break; + + case FR_TYPE_UINT64: + IN_RANGE_UNSIGNED(UINT64); + dst->datum.uint64 = (uint64_t)uinteger; + break; + + case FR_TYPE_DATE_MILLISECONDS: + IN_RANGE_UNSIGNED(UINT64); + dst->datum.date_milliseconds = (uint64_t)uinteger; + break; + + case FR_TYPE_DATE_MICROSECONDS: + IN_RANGE_UNSIGNED(UINT64); + dst->datum.date_microseconds = (uint64_t)uinteger; + break; + + case FR_TYPE_DATE_NANOSECONDS: + IN_RANGE_UNSIGNED(UINT64); + dst->datum.date_nanoseconds = (uint64_t)uinteger; + break; + + case FR_TYPE_INT8: + IN_RANGE_SIGNED(INT8); + dst->datum.int8 = (int8_t)sinteger; + break; + + case FR_TYPE_INT16: + IN_RANGE_SIGNED(INT16); + dst->datum.int16 = (int16_t)sinteger; + break; + + case FR_TYPE_INT32: + IN_RANGE_SIGNED(INT32); + dst->datum.int32 = (int32_t)sinteger; + break; + + case FR_TYPE_INT64: + IN_RANGE_SIGNED(INT64); + dst->datum.int64 = (int64_t)sinteger; + break; + + default: + if (!fr_cond_assert(0)) return -1; + } + + return 0; +} + /** Convert string value to a fr_value_box_t type * * @todo Should take taint param. @@ -2475,99 +2696,18 @@ parse: case FR_TYPE_IPV6_PREFIX: break; - case FR_TYPE_UINT8: - { - char *p; - unsigned int i; - - /* - * Note that ALL uint32s are unsigned! - */ - i = fr_strtoul(in, &p); - - /* - * Look for the named in for the given - * attribute. - */ - if (i > 255) { - fr_strerror_printf("Byte value \"%s\" is larger than 255", in); - return -1; - } - - dst->datum.uint8 = i; - break; - } - case FR_TYPE_UINT16: - { - char *p; - unsigned int i; - - /* - * Note that ALL uint32s are unsigned! - */ - i = fr_strtoul(in, &p); - - /* - * Look for the named in for the given - * attribute. - */ - if (i > 65535) { - fr_strerror_printf("Short value \"%s\" is larger than 65535", in); - return -1; - } - dst->datum.uint16 = i; - break; - } - case FR_TYPE_UINT32: - { - char *p; - unsigned long i; - int base = 10; - - /* - * Hex strings are base 16. - */ - if ((in[0] == '0') && in[1] == 'x') base = 16; - - i = strtoul(in, &p, base); - - if ((size_t)(p - in) != len) { - fr_strerror_printf("Invalid value \"%s\" for %s type", in, - fr_int2str(dict_attr_types, *dst_type, "")); - return -1; - } - - /* - * Catch and complain on overflows. - */ - if ((i == ULONG_MAX) || (i >= ((unsigned long) 1) << 32)) { - fr_strerror_printf("Integer value \"%s\" is larger than 1<<32", in); - return -1; - } - - /* - * Value is always within the limits - */ - dst->datum.uint32 = (uint32_t) i; - } - break; - case FR_TYPE_UINT64: - { - uint64_t i; - - /* - * Note that ALL uint32s are unsigned! - */ - if (sscanf(in, "%" PRIu64, &i) != 1) { - fr_strerror_printf("Failed parsing \"%s\" as unsigned 64bit uint32", in); - return -1; - } - dst->datum.uint64 = i; - } + case FR_TYPE_INT8: + case FR_TYPE_INT16: + case FR_TYPE_INT32: + case FR_TYPE_INT64: + case FR_TYPE_DATE_MILLISECONDS: + case FR_TYPE_DATE_MICROSECONDS: + case FR_TYPE_DATE_NANOSECONDS: + if (fr_value_box_integer_str(dst, *dst_type, in) < 0) return -1; break; case FR_TYPE_SIZE: @@ -2586,6 +2726,17 @@ parse: if (fr_timeval_from_str(&dst->datum.timeval, in) < 0) return -1; break; + case FR_TYPE_FLOAT32: + { + float f; + + if (sscanf(in, "%f", &f) != 1) { + fr_strerror_printf("Failed parsing \"%s\" as a float32", in); + return -1; + } + dst->datum.float32 = f; + } + case FR_TYPE_FLOAT64: { double d; @@ -2695,11 +2846,6 @@ parse: } break; - case FR_TYPE_INT32: - /* Damned code for 1 WiMAX attribute */ - dst->datum.int32 = (int32_t)strtol(in, NULL, 10); - break; - case FR_TYPE_BOOL: if ((strcmp(in, "yes") == 0) || strcmp(in, "true") == 0) { dst->datum.boolean = true; @@ -2865,17 +3011,24 @@ char *fr_value_box_asprint(TALLOC_CTX *ctx, fr_value_box_t const *data, char quo p = talloc_typed_asprintf(ctx, "%" PRIu64, data->datum.uint64); break; - case FR_TYPE_SIZE: - p = talloc_typed_asprintf(ctx, "%zu", data->datum.size); + case FR_TYPE_INT8: + p = talloc_typed_asprintf(ctx, "%d", data->datum.int8); + break; + + case FR_TYPE_INT16: + p = talloc_typed_asprintf(ctx, "%d", data->datum.int16); break; case FR_TYPE_INT32: p = talloc_typed_asprintf(ctx, "%d", data->datum.int32); break; - case FR_TYPE_TIMEVAL: - p = talloc_typed_asprintf(ctx, "%" PRIu64 ".%06" PRIu64, - (uint64_t)data->datum.timeval.tv_sec, (uint64_t)data->datum.timeval.tv_usec); + case FR_TYPE_INT64: + p = talloc_typed_asprintf(ctx, "%" PRId64, data->datum.int64); + break; + + case FR_TYPE_FLOAT32: + p = talloc_typed_asprintf(ctx, "%f", data->datum.float32); break; case FR_TYPE_FLOAT64: @@ -2895,6 +3048,28 @@ char *fr_value_box_asprint(TALLOC_CTX *ctx, fr_value_box_t const *data, char quo break; } + case FR_TYPE_DATE_MILLISECONDS: + p = talloc_typed_asprintf(ctx, "%" PRIu64, data->datum.date_milliseconds); + break; + + case FR_TYPE_DATE_MICROSECONDS: + p = talloc_typed_asprintf(ctx, "%" PRIu64, data->datum.date_microseconds); + break; + + case FR_TYPE_DATE_NANOSECONDS: + p = talloc_typed_asprintf(ctx, "%" PRIu64, data->datum.date_nanoseconds); + break; + + case FR_TYPE_SIZE: + p = talloc_typed_asprintf(ctx, "%zu", data->datum.size); + break; + + case FR_TYPE_TIMEVAL: + p = talloc_typed_asprintf(ctx, "%" PRIu64 ".%06" PRIu64, + (uint64_t)data->datum.timeval.tv_sec, (uint64_t)data->datum.timeval.tv_usec); + break; + + case FR_TYPE_ABINARY: #ifdef WITH_ASCEND_BINARY p = talloc_array(ctx, char, 128); @@ -2990,6 +3165,29 @@ size_t fr_value_box_snprint(char *out, size_t outlen, fr_value_box_t const *data return fr_snprint(out, outlen, data->datum.strvalue, data->datum.length, quote); + case FR_TYPE_IPV4_ADDR: + case FR_TYPE_IPV6_ADDR: + a = fr_inet_ntop(buf, sizeof(buf), &data->datum.ip); + len = strlen(buf); + break; + + case FR_TYPE_IPV4_PREFIX: + case FR_TYPE_IPV6_PREFIX: + a = fr_inet_ntop_prefix(buf, sizeof(buf), &data->datum.ip); + len = strlen(buf); + break; + + case FR_TYPE_IFID: + a = fr_inet_ifid_ntop(buf, sizeof(buf), data->datum.ifid); + len = strlen(buf); + break; + + case FR_TYPE_ETHERNET: + return snprintf(out, outlen, "%02x:%02x:%02x:%02x:%02x:%02x", + data->datum.ether[0], data->datum.ether[1], + data->datum.ether[2], data->datum.ether[3], + data->datum.ether[4], data->datum.ether[5]); + case FR_TYPE_UINT8: return snprintf(out, outlen, "%u", data->datum.uint8); @@ -3002,19 +3200,23 @@ size_t fr_value_box_snprint(char *out, size_t outlen, fr_value_box_t const *data case FR_TYPE_UINT64: return snprintf(out, outlen, "%" PRIu64, data->datum.uint64); - case FR_TYPE_SIZE: - return snprintf(out, outlen, "%zu", data->datum.size); + case FR_TYPE_INT8: + return snprintf(out, outlen, "%d", data->datum.int8); - case FR_TYPE_INT32: /* Damned code for 1 WiMAX attribute */ - len = snprintf(buf, sizeof(buf), "%d", data->datum.int32); - a = buf; - break; + case FR_TYPE_INT16: + return snprintf(out, outlen, "%d", data->datum.int16); - case FR_TYPE_TIMEVAL: - len = snprintf(buf, sizeof(buf), "%" PRIu64 ".%06" PRIu64, - (uint64_t)data->datum.timeval.tv_sec, (uint64_t)data->datum.timeval.tv_usec); - a = buf; - break; + case FR_TYPE_INT32: + return snprintf(out, outlen, "%d", data->datum.int32); + + case FR_TYPE_INT64: + return snprintf(out, outlen, "%" PRId64, data->datum.int64); + + case FR_TYPE_FLOAT32: + return snprintf(out, outlen, "%f", data->datum.float32); + + case FR_TYPE_FLOAT64: + return snprintf(out, outlen, "%g", data->datum.float64); case FR_TYPE_DATE: t = data->datum.date; @@ -3029,17 +3231,14 @@ size_t fr_value_box_snprint(char *out, size_t outlen, fr_value_box_t const *data a = buf; break; - case FR_TYPE_IPV4_ADDR: - case FR_TYPE_IPV6_ADDR: - a = fr_inet_ntop(buf, sizeof(buf), &data->datum.ip); - len = strlen(buf); - break; + case FR_TYPE_DATE_MILLISECONDS: + return snprintf(out, outlen, "%" PRIu64, data->datum.date_milliseconds); - case FR_TYPE_IPV4_PREFIX: - case FR_TYPE_IPV6_PREFIX: - a = fr_inet_ntop_prefix(buf, sizeof(buf), &data->datum.ip); - len = strlen(buf); - break; + case FR_TYPE_DATE_MICROSECONDS: + return snprintf(out, outlen, "%" PRIu64, data->datum.date_microseconds); + + case FR_TYPE_DATE_NANOSECONDS: + return snprintf(out, outlen, "%" PRIu64, data->datum.date_nanoseconds); case FR_TYPE_ABINARY: #ifdef WITH_ASCEND_BINARY @@ -3083,19 +3282,16 @@ size_t fr_value_box_snprint(char *out, size_t outlen, fr_value_box_t const *data } return len; - case FR_TYPE_IFID: - a = fr_inet_ifid_ntop(buf, sizeof(buf), data->datum.ifid); - len = strlen(buf); - break; - case FR_TYPE_ETHERNET: - return snprintf(out, outlen, "%02x:%02x:%02x:%02x:%02x:%02x", - data->datum.ether[0], data->datum.ether[1], - data->datum.ether[2], data->datum.ether[3], - data->datum.ether[4], data->datum.ether[5]); - case FR_TYPE_FLOAT64: - return snprintf(out, outlen, "%g", data->datum.float64); + case FR_TYPE_SIZE: + return snprintf(out, outlen, "%zu", data->datum.size); + + case FR_TYPE_TIMEVAL: + len = snprintf(buf, sizeof(buf), "%" PRIu64 ".%06" PRIu64, + (uint64_t)data->datum.timeval.tv_sec, (uint64_t)data->datum.timeval.tv_usec); + a = buf; + break; /* * Don't add default here diff --git a/src/main/cond_tokenize.c b/src/main/cond_tokenize.c index 801bb770a8d..db05f1d9095 100644 --- a/src/main/cond_tokenize.c +++ b/src/main/cond_tokenize.c @@ -274,6 +274,7 @@ static ssize_t cond_tokenize_word(TALLOC_CTX *ctx, char const *start, char **out *out = talloc_array(ctx, char, len + 1); memcpy(*out, start, len); (*out)[len] = '\0'; + return len; } diff --git a/src/main/pair.c b/src/main/pair.c index a9fb9dfc725..aa4d5ad2992 100644 --- a/src/main/pair.c +++ b/src/main/pair.c @@ -186,7 +186,7 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v ret = vp->vp_uint8 - check->vp_uint8; break; case FR_TYPE_UINT16: - ret = vp->vp_short - check->vp_short; + ret = vp->vp_uint16 - check->vp_uint16; break; case FR_TYPE_UINT32: ret = vp->vp_uint32 - check->vp_uint32; @@ -206,9 +206,9 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v break; case FR_TYPE_INT32: - if (vp->vp_signed < check->vp_signed) { + if (vp->vp_int32 < check->vp_int32) { ret = -1; - } else if (vp->vp_signed > check->vp_signed) { + } else if (vp->vp_int32 > check->vp_int32) { ret = +1; } else { ret = 0; diff --git a/src/main/trigger.c b/src/main/trigger.c index 6ac1ca0e862..7c7d8f2eba0 100644 --- a/src/main/trigger.c +++ b/src/main/trigger.c @@ -334,7 +334,7 @@ VALUE_PAIR *trigger_args_afrom_server(TALLOC_CTX *ctx, char const *server, uint1 fr_pair_cursor_append(&cursor, vp); MEM(vp = fr_pair_afrom_da(ctx, port_da)); - vp->vp_short = port; + vp->vp_uint16 = port; fr_pair_cursor_append(&cursor, vp); return out; diff --git a/src/main/unlang_interpret.c b/src/main/unlang_interpret.c index 2ad81387b30..06901d17ed5 100644 --- a/src/main/unlang_interpret.c +++ b/src/main/unlang_interpret.c @@ -202,7 +202,7 @@ static unlang_action_t unlang_load_balance(REQUEST *request, unlang_stack_t *sta break; case FR_TYPE_UINT16: - start = ((uint32_t) vp->vp_short) % g->num_children; + start = ((uint32_t) vp->vp_uint16) % g->num_children; break; case FR_TYPE_UINT32: diff --git a/src/main/xlat_func.c b/src/main/xlat_func.c index 5f851eeaa75..e09195bf690 100644 --- a/src/main/xlat_func.c +++ b/src/main/xlat_func.c @@ -132,7 +132,7 @@ static ssize_t xlat_integer(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, return snprintf(*out, outlen, "%u", (unsigned int) vp->vp_uint8); case FR_TYPE_UINT16: - return snprintf(*out, outlen, "%u", (unsigned int) vp->vp_short); + return snprintf(*out, outlen, "%u", (unsigned int) vp->vp_uint16); /* * Ethernet is weird... It's network related, so we assume to it should be @@ -143,7 +143,7 @@ static ssize_t xlat_integer(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, return snprintf(*out, outlen, "%" PRIu64, htonll(int64)); case FR_TYPE_INT32: - return snprintf(*out, outlen, "%i", vp->vp_signed); + return snprintf(*out, outlen, "%i", vp->vp_int32); case FR_TYPE_IPV6_ADDR: case FR_TYPE_IPV6_PREFIX: diff --git a/src/modules/proto_dhcp/dhcp.c b/src/modules/proto_dhcp/dhcp.c index 9f32f8439d3..ac695c34651 100644 --- a/src/modules/proto_dhcp/dhcp.c +++ b/src/modules/proto_dhcp/dhcp.c @@ -755,8 +755,8 @@ static ssize_t decode_value_internal(TALLOC_CTX *ctx, vp_cursor_t *cursor, fr_di case FR_TYPE_UINT16: if (data_len != 2) goto raw; - memcpy(&vp->vp_short, p, 2); - vp->vp_short = ntohs(vp->vp_short); + memcpy(&vp->vp_uint16, p, 2); + vp->vp_uint16 = ntohs(vp->vp_uint16); p += 2; break; @@ -1172,7 +1172,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet) break; case FR_TYPE_UINT16: - vp->vp_short = (p[0] << 8) | p[1]; + vp->vp_uint16 = (p[0] << 8) | p[1]; break; case FR_TYPE_UINT32: @@ -1275,7 +1275,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet) /* * Reply should be broadcast. */ - if (vp) vp->vp_short |= 0x8000; + if (vp) vp->vp_uint16 |= 0x8000; packet->data[10] |= 0x80; } } @@ -1387,8 +1387,8 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, break; case FR_TYPE_UINT16: - p[0] = (vp->vp_short >> 8) & 0xff; - p[1] = vp->vp_short & 0xff; + p[0] = (vp->vp_uint16 >> 8) & 0xff; + p[1] = vp->vp_uint16 & 0xff; p += 2; break; @@ -1731,14 +1731,14 @@ int fr_dhcp_encode(RADIUS_PACKET *packet) /* DHCP-Number-of-Seconds */ if ((vp = fr_pair_find_by_num(packet->vps, DHCP_MAGIC_VENDOR, 261, TAG_ANY))) { - svalue = htons(vp->vp_short); + svalue = htons(vp->vp_uint16); memcpy(p, &svalue, 2); } p += 2; /* DHCP-Flags */ if ((vp = fr_pair_find_by_num(packet->vps, DHCP_MAGIC_VENDOR, 262, TAG_ANY))) { - svalue = htons(vp->vp_short); + svalue = htons(vp->vp_uint16); memcpy(p, &svalue, 2); } p += 2; diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index 904596ac179..54702598cec 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -599,15 +599,15 @@ static rlm_rcode_t mod_cache_it(void *instance, UNUSED void *thread, REQUEST *re vp = fr_pair_find_by_num(request->control, 0, PW_CACHE_TTL, TAG_ANY); if (vp) { - if (vp->vp_signed == 0) { + if (vp->vp_int32 == 0) { expire = true; - } else if (vp->vp_signed < 0) { + } else if (vp->vp_int32 < 0) { expire = true; - ttl = -(vp->vp_signed); + ttl = -(vp->vp_int32); /* Updating the TTL */ } else { set_ttl = true; - ttl = vp->vp_signed; + ttl = vp->vp_int32; } } diff --git a/src/modules/rlm_couchbase/mod.c b/src/modules/rlm_couchbase/mod.c index de7ea442b67..e8a6290b78f 100644 --- a/src/modules/rlm_couchbase/mod.c +++ b/src/modules/rlm_couchbase/mod.c @@ -394,7 +394,7 @@ json_object *mod_value_pair_to_json_object(REQUEST *request, VALUE_PAIR *vp) goto print_int; case FR_TYPE_UINT16: - i = vp->vp_short; + i = vp->vp_uint16; goto print_int; case FR_TYPE_UINT8: @@ -420,11 +420,11 @@ json_object *mod_value_pair_to_json_object(REQUEST *request, VALUE_PAIR *vp) /* debug */ RDEBUG3("creating new int64 for signed 32 bit integer '%s'", vp->da->name); /* return as 64 bit int - json-c represents all ints as 64 bits internally */ - return json_object_new_int64(vp->vp_signed); + return json_object_new_int64(vp->vp_int32); #else RDEBUG3("creating new int for signed 32 bit integer '%s'", vp->da->name); /* return as signed int */ - return json_object_new_int(vp->vp_signed); + return json_object_new_int(vp->vp_int32); #endif case FR_TYPE_UINT64: diff --git a/src/modules/rlm_eap/lib/sim/sim_proto.c b/src/modules/rlm_eap/lib/sim/sim_proto.c index 0b53f1b5fd1..44b631818e6 100644 --- a/src/modules/rlm_eap/lib/sim/sim_proto.c +++ b/src/modules/rlm_eap/lib/sim/sim_proto.c @@ -534,7 +534,7 @@ static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, vp_cursor_t *cursor, fr_di break; case FR_TYPE_UINT16: - vp->vp_short = (p[0] << 8) | p[1]; + vp->vp_uint16 = (p[0] << 8) | p[1]; break; default: @@ -759,7 +759,7 @@ ssize_t fr_sim_encode(REQUEST *request, fr_dict_attr_t const *parent, uint8_t ty REDEBUG("Missing subtype attribute"); return -1; } - subtype = vp->vp_short; + subtype = vp->vp_uint16; vp = fr_pair_find_by_num(to_encode, 0, PW_EAP_ID, TAG_ANY); id = vp ? vp->vp_uint32 : ((int)getpid() & 0xff); diff --git a/src/modules/rlm_eap/types/rlm_eap_aka/rlm_eap_aka.c b/src/modules/rlm_eap/types/rlm_eap_aka/rlm_eap_aka.c index b6cc64e04d5..39be33350f3 100644 --- a/src/modules/rlm_eap/types/rlm_eap_aka/rlm_eap_aka.c +++ b/src/modules/rlm_eap/types/rlm_eap_aka/rlm_eap_aka.c @@ -350,7 +350,7 @@ static rlm_rcode_t mod_process(UNUSED void *arg, eap_session_t *eap_session) "has not supplied a client error code"); } else { REDEBUG("Client rejected AKA-Challenge with error: %s (%i)", - fr_pair_value_enum(vp, &buff[0]), vp->vp_short); + fr_pair_value_enum(vp, &buff[0]), vp->vp_uint16); } return RLM_MODULE_REJECT; } diff --git a/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c b/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c index 582a9f4bdd5..8c8a9b9e86e 100644 --- a/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c +++ b/src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c @@ -325,7 +325,7 @@ static int process_eap_sim_start(eap_session_t *eap_session, VALUE_PAIR *vps) return 0; } - eap_sim_version = selected_version_vp->vp_short; + eap_sim_version = selected_version_vp->vp_uint16; if (eap_sim_version != EAP_SIM_VERSION) { REDEBUG("EAP-SIM version %i is unknown", eap_sim_version); return -1; diff --git a/src/modules/rlm_json/json.c b/src/modules/rlm_json/json.c index 5b148305be0..9d6559d5aa5 100644 --- a/src/modules/rlm_json/json.c +++ b/src/modules/rlm_json/json.c @@ -222,7 +222,7 @@ size_t fr_json_from_pair(char *out, size_t outlen, VALUE_PAIR const *vp) case FR_TYPE_UINT16: if (vp->da->flags.has_value) break; - return snprintf(out, freespace, "%u", (unsigned int) vp->vp_short); + return snprintf(out, freespace, "%u", (unsigned int) vp->vp_uint16); case FR_TYPE_UINT8: if (vp->da->flags.has_value) break; @@ -230,7 +230,7 @@ size_t fr_json_from_pair(char *out, size_t outlen, VALUE_PAIR const *vp) return snprintf(out, freespace, "%u", (unsigned int) vp->vp_uint8); case FR_TYPE_INT32: - return snprintf(out, freespace, "%d", vp->vp_signed); + return snprintf(out, freespace, "%d", vp->vp_int32); default: break; diff --git a/src/modules/rlm_lua/lua.c b/src/modules/rlm_lua/lua.c index 26ce8c3d8ae..61117ee793b 100644 --- a/src/modules/rlm_lua/lua.c +++ b/src/modules/rlm_lua/lua.c @@ -54,15 +54,14 @@ static int rlm_lua_marshall(lua_State *L, VALUE_PAIR const *vp) if (!vp) return -1; switch (vp->vp_type) { - case FR_TYPE_DATE: case FR_TYPE_ETHERNET: case FR_TYPE_IPV4_ADDR: case FR_TYPE_IPV6_ADDR: case FR_TYPE_IPV4_PREFIX: case FR_TYPE_IPV6_PREFIX: case FR_TYPE_IFID: - case FR_TYPE_TLV: - case FR_TYPE_UINT64: + case FR_TYPE_TIMEVAL: + case FR_TYPE_ABINARY: fr_pair_value_snprint(buffer, sizeof(buffer), vp, '\0'); lua_pushstring(L, buffer); break; @@ -75,14 +74,71 @@ static int rlm_lua_marshall(lua_State *L, VALUE_PAIR const *vp) lua_pushlstring(L, (char const *)vp->vp_octets, vp->vp_length); /* lstring variant is embedded NULL safe */ break; + case FR_TYPE_BOOL: + lua_pushinteger(L, vp->vp_bool ? 1 : 0); + break; + case FR_TYPE_UINT8: + lua_pushinteger(L, vp->vp_uint8); + break; + case FR_TYPE_UINT16: + lua_pushinteger(L, vp->vp_uint16); + break; + case FR_TYPE_UINT32: - case FR_TYPE_INT32: lua_pushinteger(L, vp->vp_uint32); break; - default: + case FR_TYPE_UINT64: + lua_pushinteger(L, vp->vp_uint64); + break; + + case FR_TYPE_INT8: + lua_pushinteger(L, vp->vp_int8); + break; + + case FR_TYPE_INT16: + lua_pushinteger(L, vp->vp_int16); + break; + + case FR_TYPE_INT32: + lua_pushinteger(L, vp->vp_int32); + break; + + case FR_TYPE_INT64: + lua_pushinteger(L, vp->vp_int64); + break; + + case FR_TYPE_DATE: + lua_pushinteger(L, vp->vp_date); + break; + + case FR_TYPE_DATE_MILLISECONDS: + lua_pushinteger(L, vp->vp_date_milliseconds); + break; + + case FR_TYPE_DATE_MICROSECONDS: + lua_pushinteger(L, vp->vp_date_microseconds); + break; + + case FR_TYPE_DATE_NANOSECONDS: + lua_pushinteger(L, vp->vp_date_nanoseconds); + break; + + case FR_TYPE_FLOAT32: + lua_pushnumber(L, vp->vp_float32); + break; + + case FR_TYPE_FLOAT64: + lua_pushnumber(L, vp->vp_float64); + break; + + case FR_TYPE_SIZE: + lua_pushnumber(L, vp->vp_size); + break; + + case FR_TYPE_NOT_VALUES: ERROR("Cannot convert %s to Lua type", fr_int2str(dict_attr_types, vp->vp_type, "")); return -1; } @@ -116,19 +172,11 @@ static int rlm_lua_unmarshall(VALUE_PAIR **out, REQUEST *request, lua_State *L, break; } - case FR_TYPE_UINT32: - vp->vp_uint32 = (uint32_t) lua_tointeger(L, -1); - break; - case FR_TYPE_IPV4_ADDR: case FR_TYPE_COMBO_IP_ADDR: vp->vp_ipv4addr = (uint32_t) lua_tointeger(L, -1); break; - case FR_TYPE_DATE: - vp->vp_date = (uint32_t) lua_tointeger(L, -1); - break; - case FR_TYPE_OCTETS: { lua_Number number = lua_tonumber(L, -1); @@ -136,22 +184,65 @@ static int rlm_lua_unmarshall(VALUE_PAIR **out, REQUEST *request, lua_State *L, } break; + /* + * FIXME: Check to see if values overflow + */ case FR_TYPE_UINT8: vp->vp_uint8 = (uint8_t) lua_tointeger(L, -1); break; case FR_TYPE_UINT16: - vp->vp_short = (uint16_t) lua_tointeger(L, -1); + vp->vp_uint16 = (uint16_t) lua_tointeger(L, -1); break; - case FR_TYPE_INT32: - vp->vp_signed = (int32_t) lua_tointeger(L, -1); + case FR_TYPE_UINT32: + vp->vp_uint32 = (uint32_t) lua_tointeger(L, -1); break; case FR_TYPE_UINT64: vp->vp_uint64 = (uint64_t) lua_tointeger(L, -1); break; + case FR_TYPE_INT8: + vp->vp_int32 = (int8_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_INT16: + vp->vp_int32 = (int16_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_INT32: + vp->vp_int32 = (int32_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_INT64: + vp->vp_int64 = (int64_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_FLOAT32: + vp->vp_float32 = (float) lua_tonumber(L, -1); + break; + + case FR_TYPE_FLOAT64: + vp->vp_float64 = (double) lua_tonumber(L, -1); + break; + + case FR_TYPE_DATE: + vp->vp_date = (uint32_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_DATE_MILLISECONDS: + vp->vp_date_milliseconds = (uint64_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_DATE_MICROSECONDS: + vp->vp_date_microseconds = (uint64_t) lua_tointeger(L, -1); + break; + + case FR_TYPE_DATE_NANOSECONDS: + vp->vp_date_nanoseconds = (uint64_t) lua_tointeger(L, -1); + break; + default: REDEBUG("Invalid attribute type"); return -1; diff --git a/src/modules/rlm_python/rlm_python.c b/src/modules/rlm_python/rlm_python.c index 62ed8a8e916..c2bb8febce4 100644 --- a/src/modules/rlm_python/rlm_python.c +++ b/src/modules/rlm_python/rlm_python.c @@ -365,8 +365,8 @@ static int mod_populate_vptuple(PyObject *pp, VALUE_PAIR *vp) value = PyString_FromStringAndSize((char const *)vp->vp_octets, vp->vp_length); break; - case FR_TYPE_UINT32: - value = PyLong_FromUnsignedLong(vp->vp_uint32); + case FR_TYPE_BOOL: + value = PyBool_FromLong(vp->vp_bool); break; case FR_TYPE_UINT8: @@ -374,27 +374,55 @@ static int mod_populate_vptuple(PyObject *pp, VALUE_PAIR *vp) break; case FR_TYPE_UINT16: - value = PyLong_FromUnsignedLong(vp->vp_short); + value = PyLong_FromUnsignedLong(vp->vp_uint16); break; - case FR_TYPE_INT32: - value = PyLong_FromLong(vp->vp_signed); + case FR_TYPE_UINT32: + value = PyLong_FromUnsignedLong(vp->vp_uint32); break; case FR_TYPE_UINT64: value = PyLong_FromUnsignedLongLong(vp->vp_uint64); break; - case FR_TYPE_SIZE: - value = PyLong_FromUnsignedLongLong((unsigned long long)vp->vp_size); + case FR_TYPE_INT8: + value = PyLong_FromLong(vp->vp_int8); + break; + + case FR_TYPE_INT16: + value = PyLong_FromLong(vp->vp_int16); + break; + + case FR_TYPE_INT32: + value = PyLong_FromLong(vp->vp_int32); + break; + + case FR_TYPE_INT64: + value = PyLong_FromLongLong(vp->vp_int64); + break; + + case FR_TYPE_FLOAT32: + value = PyFloat_FromDouble(vp->vp_float32); break; case FR_TYPE_FLOAT64: value = PyFloat_FromDouble(vp->vp_float64); break; - case FR_TYPE_BOOL: - value = PyBool_FromLong(vp->vp_bool); + case FR_TYPE_DATE_MILLISECONDS: + value = PyLong_FromLongLong(vp->vp_date_milliseconds); + break; + + case FR_TYPE_DATE_MICROSECONDS: + value = PyLong_FromLongLong(vp->vp_date_microseconds); + break; + + case FR_TYPE_DATE_NANOSECONDS: + value = PyLong_FromLongLong(vp->vp_date_nanoseconds); + break; + + case FR_TYPE_SIZE: + value = PyLong_FromUnsignedLongLong((unsigned long long)vp->vp_size); break; case FR_TYPE_TIMEVAL: @@ -405,9 +433,7 @@ static int mod_populate_vptuple(PyObject *pp, VALUE_PAIR *vp) case FR_TYPE_IPV6_ADDR: case FR_TYPE_IPV6_PREFIX: case FR_TYPE_ETHERNET: - case FR_TYPE_COMBO_IP_ADDR: case FR_TYPE_IPV4_PREFIX: - case FR_TYPE_COMBO_IP_PREFIX: { size_t len; char buffer[256]; @@ -417,8 +443,7 @@ static int mod_populate_vptuple(PyObject *pp, VALUE_PAIR *vp) } break; - case FR_TYPE_STRUCTURAL: - case FR_TYPE_BAD: + case FR_TYPE_NOT_VALUES: rad_assert(0); return -1; } diff --git a/src/modules/rlm_unpack/rlm_unpack.c b/src/modules/rlm_unpack/rlm_unpack.c index 88634469cd5..f30b0aedb33 100644 --- a/src/modules/rlm_unpack/rlm_unpack.c +++ b/src/modules/rlm_unpack/rlm_unpack.c @@ -164,7 +164,7 @@ static ssize_t unpack_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, break; case FR_TYPE_UINT16: - cast->vp_short = ((input[offset] << 8) | input[offset + 1]); + cast->vp_uint16 = ((input[offset] << 8) | input[offset + 1]); break; case FR_TYPE_UINT64: diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 1f965d7af78..768f4118fb7 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -55,12 +55,17 @@ size_t const fr_radius_attr_sizes[FR_TYPE_MAX + 1][2] = { [FR_TYPE_IFID] = {8, 8}, [FR_TYPE_ETHERNET] = {6, 6}, - [FR_TYPE_BOOL] = {1, 1}, + [FR_TYPE_BOOL] = {1, 1}, [FR_TYPE_UINT8] = {1, 1}, - [FR_TYPE_UINT16] = {2, 2}, + [FR_TYPE_UINT16] = {2, 2}, [FR_TYPE_UINT32] = {4, 4}, [FR_TYPE_UINT64] = {8, 8}, + [FR_TYPE_INT8] = {1, 1}, + [FR_TYPE_INT16] = {2, 2}, + [FR_TYPE_INT32] = {4, 4}, + [FR_TYPE_INT64] = {8, 8}, + [FR_TYPE_DATE] = {4, 4}, [FR_TYPE_ABINARY] = {32, ~0}, diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 509ee3b7870..d494350ab86 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -1345,7 +1345,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, vp_cursor_t *cursor, fr_dic break; case FR_TYPE_UINT16: - vp->vp_short = (p[0] << 8) | p[1]; + vp->vp_uint16 = (p[0] << 8) | p[1]; break; case FR_TYPE_UINT32: diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index c8e05ce751e..0125fbbdcd0 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -423,8 +423,6 @@ static void encode_tunnel_password(uint8_t *out, ssize_t *outlen, */ ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR const *vp) { - uint32_t lvalue; - uint64_t lvalue64; size_t len; VERIFY_VP(vp); @@ -442,9 +440,9 @@ ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR cons memcpy(out, vp->vp_ptr, outlen); return outlen; - /* - * All of these values are at the same location. - */ + /* + * All of these values are at the same location. + */ case FR_TYPE_IFID: case FR_TYPE_IPV4_ADDR: case FR_TYPE_IPV6_ADDR: @@ -457,39 +455,31 @@ ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR cons break; case FR_TYPE_BOOL: - out[0] = vp->vp_uint8 & 0x01; + out[0] = vp->vp_bool ? 1 : 0; break; case FR_TYPE_UINT8: - out[0] = vp->vp_uint8 & 0xff; + out[0] = vp->vp_uint8; break; - case FR_TYPE_UINT16: - out[0] = (vp->vp_short >> 8) & 0xff; - out[1] = vp->vp_short & 0xff; + case FR_TYPE_INT8: + out[0] = vp->vp_int8; break; + case FR_TYPE_UINT16: case FR_TYPE_UINT32: - lvalue = htonl(vp->vp_uint32); - memcpy(out, &lvalue, sizeof(lvalue)); - break; - case FR_TYPE_UINT64: - lvalue64 = htonll(vp->vp_uint64); - memcpy(out, &lvalue64, sizeof(lvalue64)); - break; - - case FR_TYPE_DATE: - lvalue = htonl(vp->vp_date); - memcpy(out, &lvalue, sizeof(lvalue)); - break; - + case FR_TYPE_INT16: case FR_TYPE_INT32: + case FR_TYPE_INT64: + case FR_TYPE_DATE: { - int32_t slvalue = htonl(vp->vp_signed); - memcpy(out, &slvalue, sizeof(slvalue)); - break; + fr_value_box_t network; + + fr_value_box_hton(&network, &vp->data); + memcpy(out, (uint8_t *)&network.datum, len); } + break; case FR_TYPE_INVALID: case FR_TYPE_EXTENDED: @@ -502,9 +492,13 @@ ssize_t fr_radius_encode_value_hton(uint8_t *out, size_t outlen, VALUE_PAIR cons case FR_TYPE_STRUCT: case FR_TYPE_SIZE: case FR_TYPE_TIMEVAL: + case FR_TYPE_FLOAT32: case FR_TYPE_FLOAT64: + case FR_TYPE_DATE_MILLISECONDS: + case FR_TYPE_DATE_MICROSECONDS: + case FR_TYPE_DATE_NANOSECONDS: case FR_TYPE_MAX: - fr_strerror_printf("Cannot get data for VALUE_PAIR type %i", vp->vp_type); + fr_strerror_printf("Cannot encode data for VALUE_PAIR type %i", vp->vp_type); return -1; /* Don't add default */ @@ -786,20 +780,40 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, case FR_TYPE_IPV4_PREFIX: case FR_TYPE_ABINARY: case FR_TYPE_ETHERNET: /* just in case */ - case FR_TYPE_UINT8: case FR_TYPE_BOOL: + case FR_TYPE_UINT8: case FR_TYPE_UINT16: case FR_TYPE_UINT32: case FR_TYPE_UINT64: - case FR_TYPE_DATE: + case FR_TYPE_INT8: + case FR_TYPE_INT16: case FR_TYPE_INT32: + case FR_TYPE_INT64: + case FR_TYPE_DATE: len = fr_radius_encode_value_hton(buffer, sizeof(buffer), vp); if (len < 0) return -1; data = buffer; break; - default: /* unknown type: ignore it */ - fr_strerror_printf("ERROR: Unknown attribute type %d", da->type); + case FR_TYPE_INVALID: + case FR_TYPE_EXTENDED: + case FR_TYPE_LONG_EXTENDED: + case FR_TYPE_COMBO_IP_ADDR: /* Should have been converted to concrete equivalent */ + case FR_TYPE_COMBO_IP_PREFIX: /* Should have been converted to concrete equivalent */ + case FR_TYPE_EVS: + case FR_TYPE_VSA: + case FR_TYPE_VENDOR: + case FR_TYPE_TLV: + case FR_TYPE_STRUCT: + case FR_TYPE_SIZE: + case FR_TYPE_TIMEVAL: + case FR_TYPE_FLOAT32: + case FR_TYPE_FLOAT64: + case FR_TYPE_DATE_MILLISECONDS: + case FR_TYPE_DATE_MICROSECONDS: + case FR_TYPE_DATE_NANOSECONDS: + case FR_TYPE_MAX: + fr_strerror_printf("ERROR: Unsupported attribute type %d", da->type); return -1; }