1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <sys/socket.h>
#include <stdio.h>
#include <contrib/cleanup.h>
#include "tests/unit/test.h"
#include "lib/utils.h"
static void test_strcatdup(void **state)
{
auto_free char *empty_res = kr_strcatdup(0);
assert_null(empty_res);
auto_free char *null_res = kr_strcatdup(1, NULL);
assert_null(null_res);
auto_free char *nullcat_res = kr_strcatdup(2, NULL, "beef");
assert_string_equal(nullcat_res, "beef");
auto_free char *multi_res = kr_strcatdup(3, "need", "beef", "dead");
assert_string_equal(multi_res, "needbeefdead");
/* Test fails if this leaks. */
auto_fclose FILE* null_file = fopen("/dev/null", "r");
(void)(null_file);
/* Test fails if this leaks. */
auto_close int null_sock = socket(AF_INET, SOCK_DGRAM, 0);
(void)(null_sock);
}
static inline int test_bitcmp(const char *subnet, const char *str_addr, size_t len)
{
char addr_buf[16] = {'\0'};
kr_straddr_subnet(addr_buf, str_addr);
return kr_bitcmp(subnet, addr_buf, len);
}
static void test_straddr(void **state)
{
const char *ip4_ok = "1.2.3.0/30";
const char *ip4_bad = "1.2.3.0/33";
const char *ip4_in = "1.2.3.1";
const char *ip4_out = "1.2.3.5";
const char *ip6_ok = "7caa::/4";
const char *ip6_bad = "7caa::/129";
const char *ip6_in = "7caa::aa7c";
const char *ip6_out = "8caa::aa7c";
/* Parsing family */
assert_int_equal(kr_straddr_family(ip4_ok), AF_INET);
assert_int_equal(kr_straddr_family(ip4_in), AF_INET);
assert_int_equal(kr_straddr_family(ip6_ok), AF_INET6);
assert_int_equal(kr_straddr_family(ip6_in), AF_INET6);
/* Parsing subnet */
char ip4_sub[4], ip6_sub[16];
assert_true(kr_straddr_subnet(ip4_sub, ip4_bad) < 0);
assert_int_equal(kr_straddr_subnet(ip4_sub, ip4_ok), 30);
assert_true(kr_straddr_subnet(ip6_sub, ip6_bad) < 0);
assert_int_equal(kr_straddr_subnet(ip6_sub, ip6_ok), 4);
/* Matching subnet */
assert_int_equal(test_bitcmp(ip4_sub, ip4_in, 30), 0);
assert_int_not_equal(test_bitcmp(ip4_sub, ip4_out, 30), 0);
assert_int_equal(test_bitcmp(ip6_sub, ip6_in, 4), 0);
assert_int_not_equal(test_bitcmp(ip6_sub, ip6_out, 4), 0);
}
static inline int assert_bitmask(const char *addr, const char *exp_masked)
{
unsigned char addr_buf[16];
unsigned char exp_masked_buf[16];
int bits = kr_straddr_subnet(addr_buf, addr);
size_t addr_len = (kr_straddr_family(addr) == AF_INET6) ? 16 : 4;
int exp_masked_bits = kr_straddr_subnet(exp_masked_buf, exp_masked);
size_t exp_masked_len = (kr_straddr_family(exp_masked) == AF_INET6) ? 16 : 4;
/* sanity checks */
assert_true(bits >= 0);
assert_int_equal(addr_len, exp_masked_len);
assert_int_equal(exp_masked_bits, exp_masked_len * 8);
kr_bitmask(addr_buf, addr_len, bits);
return memcmp(addr_buf, exp_masked_buf, addr_len);
}
static void test_bitmask(void **state)
{
assert_int_equal(assert_bitmask("10.0.1.5/32", "10.0.1.5"), 0);
assert_int_equal(assert_bitmask("10.0.1.5", "10.0.1.5"), 0);
assert_int_equal(assert_bitmask("10.0.1.5/24", "10.0.1.0"), 0);
assert_int_equal(assert_bitmask("128.30.1.16/16", "128.30.0.0"), 0);
assert_int_equal(assert_bitmask("255.255.255.255/20", "255.255.240.0"), 0);
assert_int_equal(assert_bitmask("255.255.255.255/22", "255.255.252.0"), 0);
assert_int_equal(assert_bitmask("192.168.0.1/0", "0.0.0.0"), 0);
assert_int_equal(assert_bitmask("7caa::/4", "7000::"), 0);
assert_int_equal(assert_bitmask("dead:beef::/16", "dead::"), 0);
assert_int_equal(assert_bitmask("dead:beef::/20", "dead:b000::"), 0);
assert_int_equal(assert_bitmask("dead:beef::/0", "::"), 0);
assert_int_equal(assert_bitmask("64aa:22fa:1378:aaaa:bbbb::/36", "64aa:22fa:1000::"), 0);
}
static void test_strptime_diff(void **state)
{
char *format = "%Y-%m-%dT%H:%M:%S";
const char *errmsg = NULL;
double output;
errmsg = kr_strptime_diff(format,
"2019-01-09T12:06:04",
"2019-01-09T12:06:04", &output);
assert_true(errmsg == NULL);
/* double type -> equality is not reliable */
assert_true(output > -0.01 && output < 0.01);
errmsg = kr_strptime_diff(format,
"2019-01-09T12:06:04",
"2019-01-09T11:06:04", &output);
assert_true(errmsg == NULL);
/* double type -> equality is not reliable */
assert_true(output > -3600.01 && output < 3600.01);
/* invalid inputs */
errmsg = kr_strptime_diff(format,
"2019-01-09T25:06:04",
"2019-01-09T11:06:04", &output);
assert_true(errmsg != NULL);
errmsg = kr_strptime_diff("fail",
"2019-01-09T23:06:04",
"2019-01-09T11:06:04", &output);
assert_true(errmsg != NULL);
}
int main(void)
{
const UnitTest tests[] = {
unit_test(test_strcatdup),
unit_test(test_straddr),
unit_test(test_bitmask),
unit_test(test_strptime_diff)
};
return run_tests(tests);
}
|