summaryrefslogtreecommitdiffstats
path: root/rtrlib/lib
diff options
context:
space:
mode:
Diffstat (limited to 'rtrlib/lib')
-rw-r--r--rtrlib/lib/alloc_utils.c81
-rw-r--r--rtrlib/lib/alloc_utils.h25
-rw-r--r--rtrlib/lib/alloc_utils_private.h34
-rw-r--r--rtrlib/lib/convert_byte_order.c34
-rw-r--r--rtrlib/lib/convert_byte_order_private.h39
-rw-r--r--rtrlib/lib/ip.c79
-rw-r--r--rtrlib/lib/ip.h87
-rw-r--r--rtrlib/lib/ip_private.h58
-rw-r--r--rtrlib/lib/ipv4.c64
-rw-r--r--rtrlib/lib/ipv4.h23
-rw-r--r--rtrlib/lib/ipv4_private.h79
-rw-r--r--rtrlib/lib/ipv6.c220
-rw-r--r--rtrlib/lib/ipv6.h22
-rw-r--r--rtrlib/lib/ipv6_private.h81
-rw-r--r--rtrlib/lib/log.c48
-rw-r--r--rtrlib/lib/log_private.h19
-rw-r--r--rtrlib/lib/utils.c54
-rw-r--r--rtrlib/lib/utils_private.h34
18 files changed, 1081 insertions, 0 deletions
diff --git a/rtrlib/lib/alloc_utils.c b/rtrlib/lib/alloc_utils.c
new file mode 100644
index 0000000..e3d6831
--- /dev/null
+++ b/rtrlib/lib/alloc_utils.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "alloc_utils_private.h"
+
+#include "rtrlib/rtrlib_export_private.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void *(*MALLOC_PTR)(size_t size) = malloc;
+static void *(*REALLOC_PTR)(void *ptr, size_t size) = realloc;
+static void (*FREE_PTR)(void *ptr) = free;
+
+/* cppcheck-suppress unusedFunction */
+RTRLIB_EXPORT void lrtr_set_alloc_functions(void *(*malloc_function)(size_t size),
+ void *(*realloc_function)(void *ptr, size_t size),
+ void(free_function)(void *ptr))
+{
+ MALLOC_PTR = malloc_function;
+ REALLOC_PTR = realloc_function;
+ FREE_PTR = free_function;
+}
+
+inline void *lrtr_malloc(size_t size)
+{
+ return MALLOC_PTR(size);
+}
+
+/* cppcheck-suppress unusedFunction */
+void *lrtr_calloc(size_t nmemb, size_t size)
+{
+ int bytes = 0;
+
+#if __GNUC__ >= 5
+ if (__builtin_mul_overflow(nmemb, size, &bytes)) {
+ errno = ENOMEM;
+ return 0;
+ }
+#else
+ if (size && nmemb > (size_t)-1 / size) {
+ errno = ENOMEM;
+ return 0;
+ }
+ bytes = size * nmemb;
+#endif
+ void *p = lrtr_malloc(bytes);
+
+ if (!p)
+ return p;
+
+ return memset(p, 0, bytes);
+}
+
+inline void lrtr_free(void *ptr)
+{
+ return FREE_PTR(ptr);
+}
+
+inline void *lrtr_realloc(void *ptr, size_t size)
+{
+ return REALLOC_PTR(ptr, size);
+}
+
+char *lrtr_strdup(const char *string)
+{
+ assert(string);
+
+ size_t length = strlen(string) + 1;
+ char *new_string = lrtr_malloc(length);
+
+ return new_string ? memcpy(new_string, string, length) : NULL;
+}
diff --git a/rtrlib/lib/alloc_utils.h b/rtrlib/lib/alloc_utils.h
new file mode 100644
index 0000000..b265915
--- /dev/null
+++ b/rtrlib/lib/alloc_utils.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_ALLOC_UTILS_H
+#define LRTR_ALLOC_UTILS_H
+
+#include <stdlib.h>
+
+/**
+ * @brief Sets custom malloc, realloc and free function
+ * that is used throughout rtrlib.
+ * @param[in] Pointer to malloc function
+ * @param[in] Pointer to realloc function
+ * @param[in] Pointer to free function
+ */
+void lrtr_set_alloc_functions(void *(*malloc_function)(size_t size), void *(*realloc_function)(void *ptr, size_t size),
+ void (*free_function)(void *ptr));
+
+#endif
diff --git a/rtrlib/lib/alloc_utils_private.h b/rtrlib/lib/alloc_utils_private.h
new file mode 100644
index 0000000..b6c67cc
--- /dev/null
+++ b/rtrlib/lib/alloc_utils_private.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_ALLOC_UTILS_PRIVATE_H
+#define LRTR_ALLOC_UTILS_PRIVATE_H
+
+#include "alloc_utils.h"
+
+#include <stdlib.h>
+
+void *lrtr_malloc(size_t size);
+
+void *lrtr_calloc(size_t nmemb, size_t size);
+
+void lrtr_free(void *ptr);
+
+void *lrtr_realloc(void *ptr, size_t size);
+
+/**
+ * @brief Duplicates a string
+ * @pre string != NULL
+ * @param[in] string
+ * @returns Duplicated string
+ * @returns NULL on error
+ */
+char *lrtr_strdup(const char *string);
+
+#endif
diff --git a/rtrlib/lib/convert_byte_order.c b/rtrlib/lib/convert_byte_order.c
new file mode 100644
index 0000000..402c141
--- /dev/null
+++ b/rtrlib/lib/convert_byte_order.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "convert_byte_order_private.h"
+
+#include <arpa/inet.h>
+#include <assert.h>
+#include <inttypes.h>
+
+uint16_t lrtr_convert_short(const enum target_byte_order tbo, const uint16_t value)
+{
+ if (tbo == TO_NETWORK_BYTE_ORDER)
+ return htons(value);
+ else if (tbo == TO_HOST_HOST_BYTE_ORDER)
+ return ntohs(value);
+
+ assert(0);
+}
+
+uint32_t lrtr_convert_long(const enum target_byte_order tbo, const uint32_t value)
+{
+ if (tbo == TO_NETWORK_BYTE_ORDER)
+ return htonl(value);
+ else if (tbo == TO_HOST_HOST_BYTE_ORDER)
+ return ntohl(value);
+
+ assert(0);
+}
diff --git a/rtrlib/lib/convert_byte_order_private.h b/rtrlib/lib/convert_byte_order_private.h
new file mode 100644
index 0000000..839f82b
--- /dev/null
+++ b/rtrlib/lib/convert_byte_order_private.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_CONVERT_BYTE_ORDER_PRIVATE_H
+#define LRTR_CONVERT_BYTE_ORDER_PRIVATE_H
+
+#include <inttypes.h>
+
+/**
+ * @brief Target byte order for conversion.
+ */
+enum target_byte_order {
+ TO_NETWORK_BYTE_ORDER,
+ TO_HOST_HOST_BYTE_ORDER,
+};
+
+/**
+ * Converts the passed short value to the given target byte order.
+ * @param[in] tbo Target byte order.
+ * @param[in] value Input (uint16_t) for conversion.
+ * @result Converted uint16_t value.
+ */
+uint16_t lrtr_convert_short(const enum target_byte_order tbo, const uint16_t value);
+
+/**
+ * Converts the passed long value to the given target byte order.
+ * @param[in] tbo Target byte order.
+ * @param[in] value Input (uint32_t) for conversion.
+ * @result Converted uint32_t value.
+ */
+uint32_t lrtr_convert_long(const enum target_byte_order tbo, const uint32_t value);
+
+#endif /* LRTR_CONVERT_BYTE_ORDER_H */
diff --git a/rtrlib/lib/ip.c b/rtrlib/lib/ip.c
new file mode 100644
index 0000000..39df774
--- /dev/null
+++ b/rtrlib/lib/ip.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "ip_private.h"
+
+#include "rtrlib/rtrlib_export_private.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+bool lrtr_ip_addr_is_zero(const struct lrtr_ip_addr prefix)
+{
+ if (prefix.ver == LRTR_IPV6) {
+ if (prefix.u.addr6.addr[0] == 0 && prefix.u.addr6.addr[1] == 0 && prefix.u.addr6.addr[2] == 0 &&
+ prefix.u.addr6.addr[3] == 0) {
+ return true;
+ }
+ } else if (prefix.u.addr4.addr == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+struct lrtr_ip_addr lrtr_ip_addr_get_bits(const struct lrtr_ip_addr *val, const uint8_t from, const uint8_t number)
+{
+ struct lrtr_ip_addr result;
+
+ if (val->ver == LRTR_IPV6) {
+ result.ver = LRTR_IPV6;
+ result.u.addr6 = lrtr_ipv6_get_bits(&(val->u.addr6), from, number);
+ } else {
+ result.ver = LRTR_IPV4;
+ result.u.addr4 = lrtr_ipv4_get_bits(&(val->u.addr4), from, number);
+ }
+ return result;
+}
+
+RTRLIB_EXPORT bool lrtr_ip_addr_equal(const struct lrtr_ip_addr a, const struct lrtr_ip_addr b)
+{
+ if (a.ver != b.ver)
+ return false;
+ if (a.ver == LRTR_IPV6)
+ return lrtr_ipv6_addr_equal(&(a.u.addr6), &(b.u.addr6));
+ return lrtr_ipv4_addr_equal(&(a.u.addr4), &(b.u.addr4));
+}
+
+RTRLIB_EXPORT int lrtr_ip_addr_to_str(const struct lrtr_ip_addr *ip, char *str, const unsigned int len)
+{
+ if (ip->ver == LRTR_IPV6)
+ return lrtr_ipv6_addr_to_str(&(ip->u.addr6), str, len);
+ return lrtr_ipv4_addr_to_str(&(ip->u.addr4), str, len);
+}
+
+RTRLIB_EXPORT int lrtr_ip_str_to_addr(const char *str, struct lrtr_ip_addr *ip)
+{
+ if (!strchr(str, ':')) {
+ ip->ver = LRTR_IPV4;
+ return lrtr_ipv4_str_to_addr(str, &(ip->u.addr4));
+ }
+ ip->ver = LRTR_IPV6;
+ return lrtr_ipv6_str_to_addr(str, &(ip->u.addr6));
+}
+
+// cppcheck-suppress unusedFunction
+RTRLIB_EXPORT bool lrtr_ip_str_cmp(const struct lrtr_ip_addr *addr1, const char *addr2)
+{
+ struct lrtr_ip_addr tmp;
+
+ if (lrtr_ip_str_to_addr(addr2, &tmp) == -1)
+ return false;
+ return lrtr_ip_addr_equal(*addr1, tmp);
+}
diff --git a/rtrlib/lib/ip.h b/rtrlib/lib/ip.h
new file mode 100644
index 0000000..df3bb06
--- /dev/null
+++ b/rtrlib/lib/ip.h
@@ -0,0 +1,87 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_IP_PUBLIC_H
+#define LRTR_IP_PUBLIC_H
+
+#include "rtrlib/lib/ipv4.h"
+#include "rtrlib/lib/ipv6.h"
+
+#include <stdbool.h>
+/**
+ * @defgroup util_h Utility functions
+ * @{
+ */
+
+/**
+ * @brief Version of the IP protocol.
+ */
+enum lrtr_ip_version {
+ /** IPV4 */
+ LRTR_IPV4,
+
+ /** LRTR_IPV6 */
+ LRTR_IPV6
+};
+
+/**
+ * @brief The lrtr_ip_addr struct stores a IPv4 or IPv6 address in host byte order.
+ * @param ver Specifies the type of the stored address.
+ * @param u Union holding a lrtr_ipv4_addr or lrtr_ipv6_addr.
+ */
+struct lrtr_ip_addr {
+ enum lrtr_ip_version ver;
+ union {
+ struct lrtr_ipv4_addr addr4;
+ struct lrtr_ipv6_addr addr6;
+ } u;
+};
+
+/**
+ * Converts the passed lrtr_ip_addr struct to string representation.
+ * @param[in] ip lrtr_ip_addr
+ * @param[out] str Pointer to a char array.
+ * The array must be at least INET_ADDRSTRLEN bytes long if the passed lrtr_ip_addr stores an IPv4 address.
+ * If lrtr_ip_addr stores an IPv6 address, str must be at least INET6_ADDRSTRLEN bytes long.
+ * @param[in] len Length of the str array.
+ * @result 0 On success.
+ * @result -1 On error.
+ */
+int lrtr_ip_addr_to_str(const struct lrtr_ip_addr *ip, char *str, const unsigned int len);
+
+/**
+ * Converts the passed IP address in string representation to an lrtr_ip_addr.
+ * @param[in] str Pointer to a Null terminated char array.
+ * @param[out] ip Pointer to a lrtr_ip_addr struct.
+ * @result 0 On success.
+ * @result -1 On error.
+ */
+int lrtr_ip_str_to_addr(const char *str, struct lrtr_ip_addr *ip);
+
+/**
+ *
+ * @brief Checks if two lrtr_ip_addr structs are equal.
+ * @param[in] a lrtr_ip_addr
+ * @param[in] b lrtr_ip_addr
+ * @return true If a == b.
+ * @return false If a != b.
+ */
+bool lrtr_ip_addr_equal(const struct lrtr_ip_addr a, const struct lrtr_ip_addr b);
+
+/**
+ * Compares addr1 in the lrtr_ip_addr struct with addr2 in string representation.
+ * @param[in] addr1 lrtr_ip_addr
+ * @param[in] addr2 IP-address as string
+ * @return true If a == b
+ * @return false If a != b
+ */
+bool lrtr_ip_str_cmp(const struct lrtr_ip_addr *addr1, const char *addr2);
+
+#endif
+/** @} */
diff --git a/rtrlib/lib/ip_private.h b/rtrlib/lib/ip_private.h
new file mode 100644
index 0000000..623fd96
--- /dev/null
+++ b/rtrlib/lib/ip_private.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_IP_PRIVATE_H
+#define LRTR_IP_PRIVATE_H
+
+#include "ip.h"
+
+#include "rtrlib/lib/ipv4_private.h"
+#include "rtrlib/lib/ipv6_private.h"
+
+/**
+ * @brief Detects if the lrtr_ip_addr only contains 0 bits.
+ * @param[in] lrtr_ip_addr
+ * @returns true If the saved lrtr_ip_addr is 0.
+ * @returns false If the saved lrtr_ip_addr isn't 0.
+ */
+bool lrtr_ip_addr_is_zero(const struct lrtr_ip_addr);
+
+/**
+ * @brief Extracts number bits from the passed lrtr_ip_addr, starting at bit number from. The bit with the highest
+ * significance is bit 0. All bits that aren't in the specified range will be 0.
+ * @param[in] val lrtr_ip_addr
+ * @param[in] from Position of the first bit that is extracted.
+ * @param[in] number How many bits will be extracted.
+ * @returns An lrtr_ipv_addr, where all bits that aren't in the specified range are set to 0.
+ */
+struct lrtr_ip_addr lrtr_ip_addr_get_bits(const struct lrtr_ip_addr *val, const uint8_t from, const uint8_t number);
+
+/**
+ * @defgroup util_h Utility functions
+ * @{
+ *
+ * @brief Checks if two lrtr_ip_addr structs are equal.
+ * @param[in] a lrtr_ip_addr
+ * @param[in] b lrtr_ip_addr
+ * @return true If a == b.
+ * @return false If a != b.
+ */
+bool lrtr_ip_addr_equal(const struct lrtr_ip_addr a, const struct lrtr_ip_addr b);
+
+/**
+ * Compares addr1 in the lrtr_ip_addr struct with addr2 in string representation.
+ * @param[in] addr1 lrtr_ip_addr
+ * @param[in] addr2 IP-address as string
+ * @return true If a == b
+ * @return false If a != b
+ */
+bool lrtr_ip_str_cmp(const struct lrtr_ip_addr *addr1, const char *addr2);
+
+#endif
+/** @} */
diff --git a/rtrlib/lib/ipv4.c b/rtrlib/lib/ipv4.c
new file mode 100644
index 0000000..d7f10e1
--- /dev/null
+++ b/rtrlib/lib/ipv4.c
@@ -0,0 +1,64 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "ipv4_private.h"
+
+#include "rtrlib/lib/convert_byte_order_private.h"
+#include "rtrlib/lib/utils_private.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+struct lrtr_ipv4_addr lrtr_ipv4_get_bits(const struct lrtr_ipv4_addr *val, const uint8_t from, const uint8_t quantity)
+{
+ struct lrtr_ipv4_addr result;
+
+ result.addr = lrtr_get_bits(val->addr, from, quantity);
+ return result;
+}
+
+int lrtr_ipv4_addr_to_str(const struct lrtr_ipv4_addr *ip, char *str, unsigned int len)
+{
+ uint8_t buff[4];
+
+ buff[0] = ip->addr >> 24 & 0xff;
+ buff[1] = ip->addr >> 16 & 0xff;
+ buff[2] = ip->addr >> 8 & 0xff;
+ buff[3] = ip->addr & 0xff;
+
+ if (snprintf(str, len, "%hhu.%hhu.%hhu.%hhu", buff[0], buff[1], buff[2], buff[3]) < 0)
+ return -1;
+
+ return 0;
+}
+
+int lrtr_ipv4_str_to_addr(const char *str, struct lrtr_ipv4_addr *ip)
+{
+ uint8_t buff[4];
+
+ if (sscanf(str, "%3hhu.%3hhu.%3hhu.%3hhu", &buff[0], &buff[1], &buff[2], &buff[3]) != 4)
+ return -1;
+
+ ip->addr = buff[0] << 24 | buff[1] << 16 | buff[2] << 8 | buff[3];
+
+ return 0;
+}
+
+bool lrtr_ipv4_addr_equal(const struct lrtr_ipv4_addr *a, const struct lrtr_ipv4_addr *b)
+{
+ if (a->addr == b->addr)
+ return true;
+
+ return false;
+}
+
+void lrtr_ipv4_addr_convert_byte_order(const uint32_t src, uint32_t *dest, const enum target_byte_order tbo)
+{
+ *dest = lrtr_convert_long(tbo, src);
+}
diff --git a/rtrlib/lib/ipv4.h b/rtrlib/lib/ipv4.h
new file mode 100644
index 0000000..9aff5aa
--- /dev/null
+++ b/rtrlib/lib/ipv4.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_IPV4_H
+#define LRTR_IPV4_H
+
+#include <stdint.h>
+
+/**
+ * @brief Struct storing an IPv4 address in host byte order.
+ * @param addr The IPv4 address.
+ */
+struct lrtr_ipv4_addr {
+ uint32_t addr;
+};
+
+#endif
diff --git a/rtrlib/lib/ipv4_private.h b/rtrlib/lib/ipv4_private.h
new file mode 100644
index 0000000..73d0170
--- /dev/null
+++ b/rtrlib/lib/ipv4_private.h
@@ -0,0 +1,79 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_IPV4_PRIVATE_H
+#define LRTR_IPV4_PRIVATE_H
+
+#include "ipv4.h"
+
+#include "rtrlib/lib/convert_byte_order_private.h"
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+/**
+ * @brief Extracts number bits from the passed ipv4_addr,
+ *
+ * Starting at bit number from. The bit with the highest significance is bit 0.
+ * All bits that aren't in the specified range will be 0.
+ *
+ * @param[in] val ipv4_addr
+ * @param[in] from Position of the first bit that is extracted.
+ * @param[in] number How many bits will be extracted.
+ *
+ * @returns An ipv4_addr, with all bits not in the specified range set to 0.
+ */
+struct lrtr_ipv4_addr lrtr_ipv4_get_bits(const struct lrtr_ipv4_addr *val, const uint8_t from, const uint8_t number);
+
+/**
+ * @brief Converts ab IPv4 address from string to ipv4_addr struct.
+ *
+ * @param[in] str Pointer to a string buffer.
+ * @param[out] ip ipv4_addr
+ *
+ * @result 0 on success
+ * @result -1 on error
+ */
+int lrtr_ipv4_str_to_addr(const char *str, struct lrtr_ipv4_addr *ip);
+
+/**
+ * @brief Converts an ipv4_addr struct to its string representation.
+ *
+ * @param[in] ip ipv4_addr
+ * @param[out] str Pointer to a string buffer, of at least INET_ADDRSTRLEN.
+ * @param[in] length of *str
+ *
+ * @result 0 on success
+ * @result -1 on error
+ */
+int lrtr_ipv4_addr_to_str(const struct lrtr_ipv4_addr *ip, char *str, const unsigned int len);
+
+/**
+ * @brief Compares two ipv4_addr structs.
+ *
+ * @param[in] a ipv4_addr
+ * @param[in] b ipv4_addr
+ *
+ * @return true if a == b
+ * @return false if a != b
+ */
+bool lrtr_ipv4_addr_equal(const struct lrtr_ipv4_addr *a, const struct lrtr_ipv4_addr *b);
+
+/**
+ * @ingroup util_h[{
+ * @brief Converts the passed IPv4 address to given byte order.
+ *
+ * @param[in] src IPv4 address in source byte order.
+ * @param[out] dest IPv4 address in target byte order.
+ * @param[in] tbo Target byte order for address conversion.
+ * }
+ */
+void lrtr_ipv4_addr_convert_byte_order(const uint32_t src, uint32_t *dest, const enum target_byte_order tbo);
+
+#endif
diff --git a/rtrlib/lib/ipv6.c b/rtrlib/lib/ipv6.c
new file mode 100644
index 0000000..5034c3c
--- /dev/null
+++ b/rtrlib/lib/ipv6.c
@@ -0,0 +1,220 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "ipv6_private.h"
+
+#include "rtrlib/lib/convert_byte_order_private.h"
+#include "rtrlib/lib/ipv4_private.h"
+#include "rtrlib/lib/utils_private.h"
+
+#include <arpa/inet.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+inline bool lrtr_ipv6_addr_equal(const struct lrtr_ipv6_addr *a, const struct lrtr_ipv6_addr *b)
+{
+ if (a->addr[0] == b->addr[0] && a->addr[1] == b->addr[1] && a->addr[2] == b->addr[2] &&
+ a->addr[3] == b->addr[3])
+ return true;
+ return false;
+}
+
+struct lrtr_ipv6_addr lrtr_ipv6_get_bits(const struct lrtr_ipv6_addr *val, const uint8_t first_bit,
+ const uint8_t quantity)
+{
+ assert(first_bit <= 127);
+ assert(quantity <= 128);
+ assert(first_bit + quantity <= 128);
+
+ // if no bytes get extracted the result has to be 0
+ struct lrtr_ipv6_addr result;
+
+ memset(&result, 0, sizeof(result));
+
+ uint8_t bits_left = quantity;
+
+ if (first_bit <= 31) {
+ const uint8_t q = quantity > 32 ? 32 : quantity;
+
+ assert(bits_left >= q);
+ bits_left -= q;
+ result.addr[0] = lrtr_get_bits(val->addr[0], first_bit, q);
+ }
+
+ if ((first_bit <= 63) && ((first_bit + quantity) > 32)) {
+ const uint8_t fr = first_bit < 32 ? 0 : first_bit - 32;
+ const uint8_t q = bits_left > 32 ? 32 : bits_left;
+
+ assert(bits_left >= q);
+ bits_left -= q;
+ result.addr[1] = lrtr_get_bits(val->addr[1], fr, q);
+ }
+
+ if ((first_bit <= 95) && ((first_bit + quantity) > 64)) {
+ const uint8_t fr = first_bit < 64 ? 0 : first_bit - 64;
+ const uint8_t q = bits_left > 32 ? 32 : bits_left;
+
+ assert(bits_left >= q);
+ bits_left -= q;
+ result.addr[2] = lrtr_get_bits(val->addr[2], fr, q);
+ }
+
+ if ((first_bit <= 127) && ((first_bit + quantity) > 96)) {
+ const uint8_t fr = first_bit < 96 ? 0 : first_bit - 127;
+ const uint8_t q = bits_left > 32 ? 32 : bits_left;
+
+ assert(bits_left >= q);
+ result.addr[3] = lrtr_get_bits(val->addr[3], fr, q);
+ }
+ return result;
+}
+
+/*
+ * This function was copied from the bird routing daemon's ip_pton(..) function.
+ */
+int lrtr_ipv6_str_to_addr(const char *a, struct lrtr_ipv6_addr *ip)
+{
+ uint32_t *o = ip->addr;
+ uint16_t words[8];
+ int i, j, k, l, hfil;
+ const char *start;
+
+ if (a[0] == ':') { /* Leading :: */
+ if (a[1] != ':')
+ return -1;
+ a++;
+ }
+ hfil = -1;
+ i = 0;
+ while (*a) {
+ if (*a == ':') { /* :: */
+ if (hfil >= 0)
+ return -1;
+ hfil = i;
+ a++;
+ continue;
+ }
+ j = 0;
+ l = 0;
+ start = a;
+ for (;;) {
+ if (*a >= '0' && *a <= '9')
+ k = *a++ - '0';
+ else if (*a >= 'A' && *a <= 'F')
+ k = *a++ - 'A' + 10;
+ else if (*a >= 'a' && *a <= 'f')
+ k = *a++ - 'a' + 10;
+ else
+ break;
+ j = (j << 4) + k;
+ if (j >= 0x10000 || ++l > 4)
+ return -1;
+ }
+ if (*a == ':' && a[1]) {
+ a++;
+ } else if (*a == '.' && (i == 6 || (i < 6 && hfil >= 0))) { /* Embedded IPv4 address */
+ struct lrtr_ipv4_addr addr4;
+
+ if (lrtr_ipv4_str_to_addr(start, &addr4) == -1)
+ return -1;
+ words[i++] = addr4.addr >> 16;
+ words[i++] = addr4.addr;
+ break;
+ } else if (*a) {
+ return -1;
+ }
+ if (i >= 8)
+ return -1;
+ words[i++] = j;
+ }
+
+ /* Replace :: with an appropriate quantity of zeros */
+ if (hfil >= 0) {
+ j = 8 - i;
+ for (i = 7; i - j >= hfil; i--)
+ words[i] = words[i - j];
+ for (; i >= hfil; i--)
+ words[i] = 0;
+ }
+
+ /* Convert the address to lrtr_ip_addr format */
+ for (i = 0; i < 4; i++)
+ o[i] = (words[2 * i] << 16) | words[2 * i + 1];
+ return 0;
+}
+
+/*
+ * This function was copied from the bird routing daemon's ip_ntop(..) function.
+ */
+int lrtr_ipv6_addr_to_str(const struct lrtr_ipv6_addr *ip_addr, char *b, const unsigned int len)
+{
+ if (len < INET6_ADDRSTRLEN)
+ return -1;
+ const uint32_t *a = ip_addr->addr;
+ uint16_t words[8];
+ int bestpos = 0;
+ int bestlen = 0;
+ int curpos = 0;
+ int curlen = 0;
+ int i;
+
+ /* First of all, preprocess the address and find the longest run of zeros */
+ for (i = 0; i < 8; i++) {
+ uint32_t x = a[i / 2];
+
+ words[i] = ((i % 2) ? x : (x >> 16)) & 0xffff;
+ if (words[i]) {
+ curlen = 0;
+ } else {
+ if (!curlen)
+ curpos = i;
+ curlen++;
+ if (curlen > bestlen) {
+ bestpos = curpos;
+ bestlen = curlen;
+ }
+ }
+ }
+ if (bestlen < 2)
+ bestpos = -1;
+
+ /* Is it an encapsulated IPv4 address? */
+ if (!bestpos && ((bestlen == 5 && a[2] == 0xffff) || bestlen == 6))
+ // if (!bestpos && ((bestlen == 5 && (a[2] == 0xffff)) || bestlen == 6))
+ {
+ uint32_t x = a[3];
+
+ b += sprintf(b, "::%s%d.%d.%d.%d", a[2] ? "ffff:" : "", ((x >> 24) & 0xff), ((x >> 16) & 0xff),
+ ((x >> 8) & 0xff), (x & 0xff));
+ return 0;
+ }
+
+ /* Normal IPv6 formatting, compress the largest sequence of zeros */
+ for (i = 0; i < 8; i++) {
+ if (i == bestpos) {
+ i += bestlen - 1;
+ *b++ = ':';
+ if (i == 7)
+ *b++ = ':';
+ } else {
+ if (i)
+ *b++ = ':';
+ b += sprintf(b, "%x", words[i]);
+ }
+ }
+ *b = '\0';
+ return 0;
+}
+
+void lrtr_ipv6_addr_convert_byte_order(const uint32_t *src, uint32_t *dest, const enum target_byte_order tbo)
+{
+ for (int i = 0; i < 4; i++)
+ dest[i] = lrtr_convert_long(tbo, src[i]);
+}
diff --git a/rtrlib/lib/ipv6.h b/rtrlib/lib/ipv6.h
new file mode 100644
index 0000000..6be7485
--- /dev/null
+++ b/rtrlib/lib/ipv6.h
@@ -0,0 +1,22 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_IPV6_PUBLIC_H
+#define LRTR_IPV6_PUBLIC_H
+
+#include <stdint.h>
+
+/**
+ * @brief Struct holding an IPv6 address in host byte order.
+ */
+struct lrtr_ipv6_addr {
+ uint32_t addr[4]; /**< The IPv6 address. */
+};
+
+#endif /* LRTR_IPV6_PUBLIC_H */
diff --git a/rtrlib/lib/ipv6_private.h b/rtrlib/lib/ipv6_private.h
new file mode 100644
index 0000000..1007e73
--- /dev/null
+++ b/rtrlib/lib/ipv6_private.h
@@ -0,0 +1,81 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_IPV6_PRIVATE_H
+#define LRTR_IPV6_PRIVATE_H
+
+#include "ipv6.h"
+
+#include "rtrlib/lib/convert_byte_order_private.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+/**
+ * @brief Compares two lrtr_ipv6_addr structs
+ *
+ * @param[in] a lrtr_ipv6_addr
+ * @param[in] b lrtr_ipv6_addr
+ *
+ * @return true if a == b
+ * @return false if a != b
+ */
+bool lrtr_ipv6_addr_equal(const struct lrtr_ipv6_addr *a, const struct lrtr_ipv6_addr *b);
+
+/**
+ * @brief Extracts quantity bits from an IPv6 address.
+ *
+ * The bit with the highest significance is bit 0. All bits that aren't in the
+ * specified range will be 0.
+ *
+ * @param[in] val ipv6_addr
+ * @param[in] first_bit Position of the first bit that is extracted, inclusive.
+ * @param[in] quantity How many bits will be extracted.
+ *
+ * @returns ipv6_addr, with all bits not in specified range set to 0.
+ */
+struct lrtr_ipv6_addr lrtr_ipv6_get_bits(const struct lrtr_ipv6_addr *val, const uint8_t first_bit,
+ const uint8_t quantity);
+
+/**
+ * @brief Converts the passed ipv6_addr to string representation
+ *
+ * @param[in] ip_addr Pointer to an IPv6 address
+ * @param[out] str Pointer to string buf, at least INET6_ADDRSTRLEN bytes.
+ * @param[in] len Length of string buffer @p str
+ *
+ * @result 0 on success
+ * @result -1 on error
+ */
+int lrtr_ipv6_addr_to_str(const struct lrtr_ipv6_addr *ip, char *str, const unsigned int len);
+
+/**
+ * @brief Converts the passed IPv6 address string in to lrtr_ipv6_addr struct.
+ *
+ * @param[in] str Pointer to a string buffer
+ * @param[out] ip Pointer to lrtr_ipv6_addr
+ *
+ * @result 0 on success
+ * @result -1 on error
+ */
+int lrtr_ipv6_str_to_addr(const char *str, struct lrtr_ipv6_addr *ip);
+
+/**
+ * @ingroup util_h
+ * @{
+ * @brief Converts the passed IPv6 address to given byte order.
+ *
+ * @param[in] src IPv6 address (uint32_t array) in source byte order.
+ * @param[out] dest IPv6 address (uint32_t array) in target byte order.
+ * @param[in] tbo Target byte order for address conversion.
+ */
+void lrtr_ipv6_addr_convert_byte_order(const uint32_t *src, uint32_t *dest, const enum target_byte_order tbo);
+/** @} */
+#endif /* LRTR_IPV6_H */
diff --git a/rtrlib/lib/log.c b/rtrlib/lib/log.c
new file mode 100644
index 0000000..6ceaaa3
--- /dev/null
+++ b/rtrlib/lib/log.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "log_private.h"
+
+#include <arpa/inet.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+
+void lrtr_dbg(const char *frmt, ...)
+{
+#ifndef NDEBUG
+ va_list argptr;
+ struct timeval tv;
+ struct timezone tz;
+
+ va_start(argptr, frmt);
+
+ bool fail = true;
+
+ if (gettimeofday(&tv, &tz) == 0) {
+ struct tm tm;
+
+ if (localtime_r(&tv.tv_sec, &tm)) {
+ fprintf(stderr, "(%04d/%02d/%02d %02d:%02d:%02d:%06ld): ", tm.tm_year + 1900, tm.tm_mon + 1,
+ tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec);
+ fail = false;
+ }
+ }
+
+ if (fail)
+ fprintf(stderr, "(%jd): ", (intmax_t)time(0));
+
+ vfprintf(stderr, frmt, argptr);
+ fprintf(stderr, "\n");
+ va_end(argptr);
+#endif
+}
diff --git a/rtrlib/lib/log_private.h b/rtrlib/lib/log_private.h
new file mode 100644
index 0000000..e33ebf3
--- /dev/null
+++ b/rtrlib/lib/log_private.h
@@ -0,0 +1,19 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_LOG_PRIVATE_H
+#define LRTR_LOG_PRIVATE_H
+
+/**
+ * @brief Writes a message to stdout if NDEBUG isn't defined.
+ * @param[in] frmt log message in printf format style.
+ */
+void lrtr_dbg(const char *frmt, ...) __attribute__((format(printf, 1, 2)));
+
+#endif
diff --git a/rtrlib/lib/utils.c b/rtrlib/lib/utils.c
new file mode 100644
index 0000000..ca708e9
--- /dev/null
+++ b/rtrlib/lib/utils.c
@@ -0,0 +1,54 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#include "utils_private.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <time.h>
+
+#ifdef __MACH__
+#include <mach/mach_time.h>
+static double timeconvert = 0.0;
+#endif
+
+int lrtr_get_monotonic_time(time_t *seconds)
+{
+#ifdef __MACH__
+ if (timeconvert == 0.0) {
+ mach_timebase_info_data_t time_base;
+ (void)mach_timebase_info(&time_base);
+ timeconvert = (double)time_base.numer / (double)time_base.denom / 1000000000.0;
+ }
+ *seconds = (time_t)mach_absolute_time() * timeconvert;
+#else
+ struct timespec time;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &time) == -1)
+ return -1;
+ *seconds = time.tv_sec;
+ if ((time.tv_nsec * 1000000000) >= 5)
+ *seconds += 1;
+#endif
+ return 0;
+}
+
+uint32_t lrtr_get_bits(const uint32_t val, const uint8_t from, const uint8_t number)
+{
+ assert(number < 33);
+ assert(number > 0);
+
+ uint32_t mask = ~0;
+
+ if (number != 32)
+ mask = ~(mask >> number);
+
+ mask >>= from;
+ return (mask & val);
+}
diff --git a/rtrlib/lib/utils_private.h b/rtrlib/lib/utils_private.h
new file mode 100644
index 0000000..40e99ee
--- /dev/null
+++ b/rtrlib/lib/utils_private.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of RTRlib.
+ *
+ * This file is subject to the terms and conditions of the MIT license.
+ * See the file LICENSE in the top level directory for more details.
+ *
+ * Website: http://rtrlib.realmv6.org/
+ */
+
+#ifndef LRTR_UTILS_PRIVATE_H
+#define LRTR_UTILS_PRIVATE_H
+
+#include <stdint.h>
+#include <time.h>
+
+/**
+ * @brief Returns the current time of the CLOCK_MONOTONIC clock.
+ * @param[in] seconds Time in seconds since some unspecified starting point.
+ * @return 0 on successs
+ * @return -1 on error
+ */
+int lrtr_get_monotonic_time(time_t *seconds);
+
+/**
+ * @brief Extracts number bits from the passed uint32_t, starting at bit number from. The bit with the highest
+ * significance is bit 0. All bits that aren't in the specified range will be 0.
+ * @param[in] val uint32_t
+ * @param[in] from Position of the first bit that is extracted.
+ * @param[in] number How many bits will be extracted.
+ * @returns a uint32_t, where all bits that aren't in the specified range are set to 0.
+ */
+uint32_t lrtr_get_bits(const uint32_t val, const uint8_t from, const uint8_t number);
+
+#endif