--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef _FR_CBUFF_H
+#define _FR_CBUFF_H
+/*
+ * $Id$
+ *
+ * @file include/cbuff.h
+ * @brief Simple circular buffer for debugging purposes.
+ *
+ * @copyright 2015-2017 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ */
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct fr_cbuff fr_cbuff_t;
+
+fr_cbuff_t *fr_cbuff_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock);
+void fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj);
+void *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx);
+#endif /* _FR_CBUFF_H */
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef _FR_DEBUG_H
+#define _FR_DEBUG_H
+/*
+ * $Id$
+ *
+ * @file include/debug.h
+ * @brief Debugging function definitions and structures.
+ *
+ * @copyright 2015-2017 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ */
+#include <freeradius-devel/cbuff.h>
+
+typedef enum {
+ DEBUGGER_STATE_UNKNOWN_NO_PTRACE = -3, //!< We don't have ptrace so can't check.
+ DEBUGGER_STATE_UNKNOWN_NO_PTRACE_CAP = -2, //!< CAP_SYS_PTRACE not set for the process.
+ DEBUGGER_STATE_UNKNOWN = -1, //!< Unknown, likely fr_get_debug_state() not called yet.
+ DEBUGGER_STATE_NOT_ATTACHED = 0, //!< We can attach, so a debugger must not be.
+ DEBUGGER_STATE_ATTACHED = 1 //!< We can't attach, it's likely a debugger is already tracing.
+} fr_debug_state_t;
+
+extern fr_debug_state_t fr_debug_state;
+
+#define FR_FAULT_LOG(fmt, ...) fr_fault_log(fmt "\n", ## __VA_ARGS__)
+typedef void (*fr_fault_log_t)(char const *msg, ...) CC_HINT(format (printf, 1, 2));
+
+/** Optional callback passed to fr_fault_setup
+ *
+ * Allows optional logic to be run before calling the main fault handler.
+ *
+ * If the callback returns < 0, the main fault handler will not be called.
+ *
+ * @param signum signal raised.
+ * @return
+ * - 0 on success.
+ * - < 0 on failure.
+ */
+typedef int (*fr_fault_cb_t)(int signum);
+typedef struct fr_bt_marker fr_bt_marker_t;
+
+void fr_debug_state_store(void);
+char const *fr_debug_state_to_msg(fr_debug_state_t state);
+void fr_debug_break(bool always);
+void backtrace_print(fr_cbuff_t *cbuff, void *obj);
+int fr_backtrace_do(fr_bt_marker_t *marker);
+fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj);
+
+void fr_panic_on_free(TALLOC_CTX *ctx);
+int fr_set_dumpable_init(void);
+int fr_set_dumpable(bool allow_core_dumps);
+int fr_reset_dumpable(void);
+int fr_log_talloc_report(TALLOC_CTX *ctx);
+void fr_fault(int sig);
+void fr_talloc_fault_setup(void);
+int fr_fault_setup(char const *cmd, char const *program);
+void fr_fault_set_cb(fr_fault_cb_t func);
+void fr_fault_set_log_fd(int fd);
+void fr_fault_log(char const *msg, ...) CC_HINT(format (printf, 1, 2));
+bool fr_cond_assert_fail(char const *file, int line, char const *expr);
+
+/** Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x
+ *
+ * Should be wrapped in a condition, and if false, should cause function to return
+ * an error code. This allows control to return to the caller if a precondition is
+ * not satisfied and we're not debugging.
+ *
+ * Example:
+ @verbatim
+ if (!fr_cond_assert(request)) return -1
+ @endverbatim
+ *
+ * @param _x expression to test (should evaluate to true)
+ */
+#define fr_cond_assert(_x) (bool)((_x) ? true : (fr_cond_assert_fail(__FILE__, __LINE__, #_x) && false))
+
+void NEVER_RETURNS _fr_exit(char const *file, int line, int status);
+# define fr_exit(_x) _fr_exit(__FILE__, __LINE__, (_x))
+
+void NEVER_RETURNS _fr_exit_now(char const *file, int line, int status);
+# define fr_exit_now(_x) _fr_exit_now(__FILE__, __LINE__, (_x))
+#endif /* _FR_DEBUG_H */
#include <freeradius-devel/fr_log.h>
#include <freeradius-devel/version.h>
#include <freeradius-devel/value.h>
+#include <freeradius-devel/debug.h>
#ifdef SIZEOF_UNSIGNED_INT
# if SIZEOF_UNSIGNED_INT != 4
/* crypt wrapper from crypt.c */
int fr_crypt_check(char const *password, char const *reference_crypt);
-/* cbuff.c */
-
-typedef struct fr_cbuff fr_cbuff_t;
-
-fr_cbuff_t *fr_cbuff_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock);
-void fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj);
-void *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx);
-
-/* debug.c */
-typedef enum {
- DEBUGGER_STATE_UNKNOWN_NO_PTRACE = -3, //!< We don't have ptrace so can't check.
- DEBUGGER_STATE_UNKNOWN_NO_PTRACE_CAP = -2, //!< CAP_SYS_PTRACE not set for the process.
- DEBUGGER_STATE_UNKNOWN = -1, //!< Unknown, likely fr_get_debug_state() not called yet.
- DEBUGGER_STATE_NOT_ATTACHED = 0, //!< We can attach, so a debugger must not be.
- DEBUGGER_STATE_ATTACHED = 1 //!< We can't attach, it's likely a debugger is already tracing.
-} fr_debug_state_t;
-
-#define FR_FAULT_LOG(fmt, ...) fr_fault_log(fmt "\n", ## __VA_ARGS__)
-typedef void (*fr_fault_log_t)(char const *msg, ...) CC_HINT(format (printf, 1, 2));
-extern fr_debug_state_t fr_debug_state;
-
-/** Optional callback passed to fr_fault_setup
- *
- * Allows optional logic to be run before calling the main fault handler.
- *
- * If the callback returns < 0, the main fault handler will not be called.
- *
- * @param signum signal raised.
- * @return
- * - 0 on success.
- * - < 0 on failure.
- */
-typedef int (*fr_fault_cb_t)(int signum);
-typedef struct fr_bt_marker fr_bt_marker_t;
-
-void fr_debug_state_store(void);
-char const *fr_debug_state_to_msg(fr_debug_state_t state);
-void fr_debug_break(bool always);
-void backtrace_print(fr_cbuff_t *cbuff, void *obj);
-int fr_backtrace_do(fr_bt_marker_t *marker);
-fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj);
-
-void fr_panic_on_free(TALLOC_CTX *ctx);
-int fr_set_dumpable_init(void);
-int fr_set_dumpable(bool allow_core_dumps);
-int fr_reset_dumpable(void);
-int fr_log_talloc_report(TALLOC_CTX *ctx);
-void fr_fault(int sig);
-void fr_talloc_fault_setup(void);
-int fr_fault_setup(char const *cmd, char const *program);
-void fr_fault_set_cb(fr_fault_cb_t func);
-void fr_fault_set_log_fd(int fd);
-void fr_fault_log(char const *msg, ...) CC_HINT(format (printf, 1, 2));
-
-# ifdef WITH_VERIFY_PTR
-void fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp);
-void fr_pair_list_verify(char const *file, int line, TALLOC_CTX *expected, VALUE_PAIR *vps);
-# endif
-
-bool fr_cond_assert_fail(char const *file, int line, char const *expr);
-
-/** Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x
- *
- * Should be wrapped in a condition, and if false, should cause function to return
- * an error code. This allows control to return to the caller if a precondition is
- * not satisfied and we're not debugging.
- *
- * Example:
- @verbatim
- if (!fr_cond_assert(request)) return -1
- @endverbatim
- *
- * @param _x expression to test (should evaluate to true)
- */
-#define fr_cond_assert(_x) (bool)((_x) ? true : (fr_cond_assert_fail(__FILE__, __LINE__, #_x) && false))
-
-void NEVER_RETURNS _fr_exit(char const *file, int line, int status);
-# define fr_exit(_x) _fr_exit(__FILE__, __LINE__, (_x))
-
-void NEVER_RETURNS _fr_exit_now(char const *file, int line, int status);
-# define fr_exit_now(_x) _fr_exit_now(__FILE__, __LINE__, (_x))
-
/*
* FIFOs
*/
#define NUM_COUNT (INT_MIN + 2)
#define NUM_LAST (INT_MIN + 3)
+# ifdef WITH_VERIFY_PTR
+void fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp);
+void fr_pair_list_verify(char const *file, int line, TALLOC_CTX *expected, VALUE_PAIR *vps);
+# endif
+
/* Allocation and management */
VALUE_PAIR *fr_pair_alloc(TALLOC_CTX *ctx);
VALUE_PAIR *fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da);
#define _FR_VALUE_H
#include <freeradius-devel/inet.h>
#include <freeradius-devel/types.h>
+#include <freeradius-devel/debug.h>
/*
* Avoid circular type references.
* These macros will in future do type checking in developer builds,
* in addition to getting the box value.
*/
-#define fr_unbox_strvalue(_box) _box->datum.strvalue
-#define fr_unbox_octets(_box) _box->datum.octets
-
-#define fr_unbox_ipv4addr(_box) _box->datum.ip
-#define fr_unbox_ipv4prefix(_box) _box->datum.ip
-#define fr_unbox_ipv6addr(_box) _box->datum.ip
-#define fr_unbox_ipv6prefix(_box) _box->datum.ip
-
-#define fr_unbox_ifid(_box) _box->datum.ifid
-#define fr_unbox_ether(_box) _box->datum.ether
-
-#define fr_unbox_uint8(_box) _box->datum.uint8
-#define fr_unbox_uint16(_box) _box->datum.uint16
-#define fr_unbox_uint32(_box) _box->datum.uint32
-#define fr_unbox_uint64(_box) _box->datum.uint64
-#define fr_unbox_uint128(_box) _box->datum.uint128
-
-#define fr_unbox_int8(_box) _box->datum.int8
-#define fr_unbox_int16(_box) _box->datum.int16
-#define fr_unbox_int32(_box) _box->datum.int32
-#define fr_unbox_int64(_box) _box->datum.int64
-
-#define fr_unbox_float32(_box) _box->datum.float32
-#define fr_unbox_float64(_box) _box->datum.float64
-
-#define fr_unbox_date(_val) _box->datum.date
-#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
+#ifndef NDEBUG
+static inline char const *fr_unbox_strvalue(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_STRING)) return NULL;
+ return value->datum.strvalue;
+}
+static inline uint8_t const *fr_unbox_octets(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_OCTETS)) return NULL;
+ return value->datum.octets;
+}
+
+static inline fr_ipaddr_t const *fr_unbox_ipv4addr(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_IPV4_ADDR)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.af == AF_INET)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.prefix == 32)) return NULL;
+ return &value->datum.ip;
+}
+static inline fr_ipaddr_t const *fr_unbox_ipv4prefix(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_IPV4_ADDR)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.af == AF_INET)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.prefix <= 32)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.prefix >= 0)) return NULL;
+ return &value->datum.ip;
+}
+static inline fr_ipaddr_t const *fr_unbox_ipv6addr(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_IPV6_ADDR)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.af == AF_INET6)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.prefix == 128)) return NULL;
+ return &value->datum.ip;
+}
+static inline fr_ipaddr_t const *fr_unbox_ipv6prefix(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_IPV6_PREFIX)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.af == AF_INET6)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.prefix <= 128)) return NULL;
+ if (!fr_cond_assert(value->datum.ip.prefix >= 0)) return NULL;
+ return &value->datum.ip;
+}
+
+static inline uint8_t const *fr_unbox_ifid(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_IFID)) return NULL;
+ return value->datum.ifid;
+}
+static inline uint8_t const *fr_unbox_ether(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_ETHERNET)) return NULL;
+ return value->datum.ether;
+}
+
+static inline uint8_t fr_unbox_uint8(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT8)) return 0;
+ return value->datum.uint8;
+}
+static inline uint16_t fr_unbox_uint16(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT16)) return 0;
+ return value->datum.uint16;
+}
+static inline uint32_t fr_unbox_uint32(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT32)) return 0;
+ return value->datum.uint32;
+}
+static inline uint64_t fr_unbox_uint64(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT64)) return 0;
+ return value->datum.uint64;
+}
+/*
+static inline uint128_t fr_unbox_uint128(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT128)) return 0;
+ return value->datum.uint128;
+}
+*/
+
+static inline int8_t fr_unbox_int8(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT8)) return 0;
+ return value->datum.int8;
+}
+static inline int16_t fr_unbox_int16(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT16)) return 0;
+ return value->datum.int16;
+}
+static inline int32_t fr_unbox_int32(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT32)) return 0;
+ return value->datum.int32;
+}
+static inline int64_t fr_unbox_int64(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_UINT64)) return 0;
+ return value->datum.int64;
+}
+
+static inline float fr_unbox_float32(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_FLOAT32)) return 0;
+ return value->datum.float32;
+}
+static inline float fr_unbox_float64(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_FLOAT64)) return 0;
+ return value->datum.float64;
+}
+
+static inline uint32_t fr_unbox_date(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_DATE)) return 0;
+ return value->datum.date;
+}
+static inline uint64_t fr_unbox_date_milliseconds(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_DATE_MILLISECONDS)) return 0;
+ return value->datum.date_milliseconds;
+}
+static inline uint64_t fr_unbox_date_microseconds(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_DATE_MICROSECONDS)) return 0;
+ return value->datum.date_microseconds;
+}
+static inline uint64_t fr_unbox_date_nanoseconds(fr_value_box_t const *value)
+{
+ if (!fr_cond_assert(value->type == FR_TYPE_DATE_NANOSECONDS)) return 0;
+ return value->datum.date_nanoseconds;
+}
+#else
+# define fr_unbox_strvalue(_box) _box->datum.strvalue
+# define fr_unbox_octets(_box) _box->datum.octets
+
+# define fr_unbox_ipv4addr(_box) &(_box->datum.ip)
+# define fr_unbox_ipv4prefix(_box) &(_box->datum.ip)
+# define fr_unbox_ipv6addr(_box) &(_box->datum.ip)
+# define fr_unbox_ipv6prefix(_box) &(_box->datum.ip)
+
+# define fr_unbox_ifid(_box) _box->datum.ifid
+# define fr_unbox_ether(_box) _box->datum.ether
+
+# define fr_unbox_uint8(_box) _box->datum.uint8
+# define fr_unbox_uint16(_box) _box->datum.uint16
+# define fr_unbox_uint32(_box) _box->datum.uint32
+# define fr_unbox_uint64(_box) _box->datum.uint64
+# define fr_unbox_uint128(_box) _box->datum.uint128
+
+# define fr_unbox_int8(_box) _box->datum.int8
+# define fr_unbox_int16(_box) _box->datum.int16
+# define fr_unbox_int32(_box) _box->datum.int32
+# define fr_unbox_int64(_box) _box->datum.int64
+
+# define fr_unbox_float32(_box) _box->datum.float32
+# define fr_unbox_float64(_box) _box->datum.float64
+
+# define fr_unbox_date(_val) _box->datum.date
+# 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
+#endif
/*
* Allocation