summaryrefslogtreecommitdiffstats
path: root/lib/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src')
-rw-r--r--lib/src/name.c84
-rw-r--r--lib/src/test/CMakeLists.txt1
-rw-r--r--lib/src/test/test_ip_address.cc73
-rw-r--r--lib/src/test/test_name.cc61
-rw-r--r--lib/src/util/ip_address.c9
5 files changed, 188 insertions, 40 deletions
diff --git a/lib/src/name.c b/lib/src/name.c
index 1c933d466..f363eea90 100644
--- a/lib/src/name.c
+++ b/lib/src/name.c
@@ -251,7 +251,7 @@ int
hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix,
hicn_prefix_t *prefix)
{
- if (hicn_ip_prefix->family != AF_INET || hicn_ip_prefix->family != AF_INET6)
+ if (hicn_ip_prefix->family != AF_INET && hicn_ip_prefix->family != AF_INET6)
return HICN_LIB_ERROR_INVALID_IP_ADDRESS;
prefix->name = hicn_ip_prefix->address;
prefix->len = (u8) (hicn_ip_prefix->len);
@@ -320,6 +320,14 @@ hicn_prefix_is_v4 (const hicn_prefix_t *prefix)
* But the bits are in host order... so we cannot use builtin functions to get
* the position of the first 1 unless we swap bytes as was done previously,
* which is costly and non-essential.
+ *
+ *
+ * Example:
+ *
+ * bits | 127 .. 120 | ... | 8 9 10 11 12 13 14 15 | 0 .. 7 |
+ * diff | | ... | 1 0 1 0 0 0 0 0 | |
+ * ^
+ * bit of interest ----------------+
*/
uint64_t
@@ -329,40 +337,43 @@ _log2_nbo (uint64_t val)
uint64_t result = 0;
- if (val & 0xFFFFFFFF00000000)
- val = val >> 32;
- else
- /* The first 32 bits of val are 0 */
- result = result | 32;
-
- if (val & 0xFFFF0000)
- val = val >> 16;
- else
- result = result | 16;
-
- if (val & 0xFF00)
- val = val >> 8;
- else
- result = result | 8;
+ /* Search for the first 1, starting from left */
- /* Val now contains the byte with at last 1 bit set (host bit order) */
- if (val & 0xF0)
+ /* The first 32 bits of val are 0 */
+ if (!(val & 0x00000000FFFFFFFF))
{
- val = val >> 4;
- result = result | 4;
+ val = val >> 32;
+ result = result | 32;
}
- if (val & 0xC)
+ if (!(val & 0x0000FFFF))
{
- val = val >> 2;
- result = result | 2;
+ val = val >> 16;
+ result = result | 16;
}
- if (val & 0x2)
+
+ if (!(val & 0x00FF))
{
- val = val >> 1;
- result = result | 1;
+ val = val >> 8;
+ result = result | 8;
}
+ /* Val now contains the byte with at last 1 bit set (host bit order) */
+ if (val & 0xF0)
+ val = val >> 4;
+ else
+ result = result | 4;
+
+ if (val & 0xC)
+ val = val >> 2;
+ else
+ result = result | 2;
+
+ if (val & 0x2)
+ val = val >> 1;
+ else
+ result = result | 1;
+
return result;
}
@@ -381,13 +392,6 @@ hicn_prefix_lpm (const hicn_prefix_t *p1, const hicn_prefix_t *p2)
/*
* As the ip_address_t mimics in*_addr and has network byte order
* (and host bit order, we cannot directly use 64-bit operations:
- *
- * Example:
- *
- * bits | 7 .. 0 | 15 14 13 12 11 10 9 8 | .. | 127 .. 120 |
- * diff | | 1 0 1 0 0 0 0 0 | .. | |
- * ^
- * bit of interest ---------+
*/
prefix_len += _log2_nbo (diff);
break;
@@ -416,7 +420,9 @@ hicn_prefix_clear (hicn_prefix_t *prefix, uint8_t start_from)
* pos 7 6 5 4 3 2 1 0 (eg. start_from = 19, pos = 3)
* mask 0 0 0 0 0 1 1 1 (= 1<<pos - 1)
* */
- buffer[offset] &= 1 << (pos - 1);
+ uint8_t mask = 0xFF ^ ((1 << (8 - pos)) - 1);
+ buffer[offset] &= mask;
+
/* ... then fully clear remaining bytes */
for (uint8_t i = offset + 1; i < HICN_PREFIX_MAX_LEN; i++)
buffer[i] = 0;
@@ -454,13 +460,19 @@ hicn_prefix_snprintf (char *s, size_t size, const hicn_prefix_t *prefix)
}
uint8_t
-hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos)
+_hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos)
{
- assert (pos <= hicn_prefix_get_len (prefix));
const hicn_ip_address_t *address = hicn_prefix_get_ip_address (prefix);
return hicn_ip_address_get_bit (address, pos);
}
+uint8_t
+hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos)
+{
+ assert (pos <= hicn_prefix_get_len (prefix));
+ return _hicn_prefix_get_bit (prefix, pos);
+}
+
int
hicn_prefix_get_ip_prefix (const hicn_prefix_t *prefix,
hicn_ip_prefix_t *ip_prefix)
diff --git a/lib/src/test/CMakeLists.txt b/lib/src/test/CMakeLists.txt
index d828c8dd8..8cf4359d2 100644
--- a/lib/src/test/CMakeLists.txt
+++ b/lib/src/test/CMakeLists.txt
@@ -24,6 +24,7 @@ list(APPEND TESTS_SRC
test_validation.cc
test_bitmap.cc
test_interest_manifest.cc
+ test_ip_address.cc
test_khash.cc
test_pool.cc
test_ring.cc
diff --git a/lib/src/test/test_ip_address.cc b/lib/src/test/test_ip_address.cc
new file mode 100644
index 000000000..1a7efb603
--- /dev/null
+++ b/lib/src/test/test_ip_address.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C"
+{
+#define WITH_TESTS
+#include <hicn/util/ip_address.h>
+}
+
+#define DEFAULT_SIZE 10
+
+class IPAddressTest : public ::testing::Test
+{
+protected:
+ IPAddressTest () {}
+
+ virtual ~IPAddressTest () {}
+};
+
+TEST_F (IPAddressTest, IPAddressGetBit)
+{
+ hicn_ip_address_t a_0, a_1, a_1_0, a_1_1, a_1_48, a_1_49, a_1_63, a_1_64,
+ a_1_127;
+
+ hicn_ip_address_pton ("0::0", &a_0);
+ hicn_ip_address_pton ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &a_1);
+
+ hicn_ip_address_pton ("8000::0", &a_1_0);
+ hicn_ip_address_pton ("4000::0", &a_1_1);
+ hicn_ip_address_pton ("0:0:0:8000::0", &a_1_48);
+ hicn_ip_address_pton ("0:0:0:4000::0", &a_1_49);
+ hicn_ip_address_pton ("0:0:0:1::0", &a_1_63);
+ hicn_ip_address_pton ("0::8000:0:0:0", &a_1_64);
+ hicn_ip_address_pton ("0::1", &a_1_127);
+
+#if 0
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_0, i), 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1, i), 1);
+#endif
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_0, i), (i == 0) ? 1 : 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_1, i), (i == 1) ? 1 : 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_48, i), (i == 48) ? 1 : 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_49, i), (i == 49) ? 1 : 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_63, i), (i == 63) ? 1 : 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_64, i), (i == 64) ? 1 : 0);
+ for (unsigned i = 0; i < 128; i++)
+ EXPECT_EQ (hicn_ip_address_get_bit (&a_1_127, i), (i == 127) ? 1 : 0);
+}
diff --git a/lib/src/test/test_name.cc b/lib/src/test/test_name.cc
index dbeab96cc..cd9ff2d4d 100644
--- a/lib/src/test/test_name.cc
+++ b/lib/src/test/test_name.cc
@@ -335,3 +335,64 @@ TEST_F (NameTest, NameNToP)
rc = strcmp (dst, expected4.str ().c_str ());
EXPECT_EQ (rc, 0);
}
+
+class PrefixTest : public ::testing::Test
+{
+protected:
+ PrefixTest () {}
+
+ virtual ~PrefixTest () {}
+};
+
+#define HICN_PREFIX(P, STR) \
+ hicn_prefix_t P; \
+ hicn_ip_prefix_t _##P; \
+ EXPECT_EQ (hicn_ip_prefix_pton (STR, &_##P), 0); \
+ EXPECT_EQ (hicn_prefix_create_from_ip_prefix (&_##P, &P), 0);
+
+TEST_F (PrefixTest, PrefixClear)
+{
+ HICN_PREFIX (hp_all, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
+
+ for (unsigned i = 0; i < 127; i++)
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, i), 1);
+
+ hicn_prefix_truncate (&hp_all, 127);
+ EXPECT_EQ (hicn_prefix_get_len (&hp_all), 127);
+
+ for (unsigned i = 0; i < 126; i++)
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, i), 1) << "bit[" << i << "] != 1";
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 127), 0);
+
+ hicn_prefix_truncate (&hp_all, 126);
+ EXPECT_EQ (hicn_prefix_get_len (&hp_all), 126);
+
+ for (unsigned i = 0; i < 125; i++)
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, i), 1);
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 126), 0);
+ EXPECT_EQ (_hicn_prefix_get_bit (&hp_all, 127), 0);
+}
+
+TEST_F (PrefixTest, PrefixClear2)
+{
+ HICN_PREFIX (hp_all, "b002::3");
+
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 125), 0);
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 126), 1);
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 127), 1);
+
+ hicn_prefix_truncate (&hp_all, 127);
+ EXPECT_EQ (hicn_prefix_get_len (&hp_all), 127);
+
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 125), 0);
+ EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 126), 1);
+ EXPECT_EQ (_hicn_prefix_get_bit (&hp_all, 127), 0);
+}
+
+TEST_F (PrefixTest, PrefixLPM)
+{
+ HICN_PREFIX (b007, "b007::/64");
+ HICN_PREFIX (b009, "b009::/64");
+
+ EXPECT_EQ (hicn_prefix_lpm (&b007, &b009), (uint32_t) 12);
+}
diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c
index ba7c6475b..3624a6fca 100644
--- a/lib/src/util/ip_address.c
+++ b/lib/src/util/ip_address.c
@@ -164,7 +164,7 @@ hicn_ip_address_pton (const char *hicn_ip_address_str,
if (pton_fd <= 0)
return -1;
- return 1;
+ return 0;
}
int
@@ -292,7 +292,7 @@ hicn_ip_prefix_pton (const char *hicn_ip_address_str,
goto ERR;
free (addr);
- return 1;
+ return 0;
ERR:
free (addr);
return -1;
@@ -409,11 +409,12 @@ hicn_ip_prefix_cmp (const hicn_ip_prefix_t *prefix1,
return hicn_ip_address_cmp (&prefix1->address, &prefix2->address);
}
+/* Network byte order + host bit order */
+
uint8_t
hicn_ip_address_get_bit (const hicn_ip_address_t *address, uint8_t pos)
{
- u64 quad = address->v6.as_u64[pos / 64];
- return quad & (0x1 << pos % 64);
+ return (address->v6.as_u8[pos / 8] >> (7 - pos % 8)) & 0x1;
}
bool