aboutsummaryrefslogtreecommitdiffstats
path: root/lib/src
diff options
context:
space:
mode:
authorLuca Muscariello <muscariello@ieee.org>2022-08-04 16:06:34 +0200
committerLuca Muscariello <muscariello@ieee.org>2022-08-04 16:31:51 +0200
commit6d22a0db96aa7f8e3102ae44d00c09e36a2e9c57 (patch)
tree79546bbf09f6fbf74db7bc89117843f06ce937ea /lib/src
parent012843b1c0bc0838e69085ed83a79ec8b6f97360 (diff)
feat: Due to the deep modifications related to names and packet format,
this task cover a large part of the codebase and involves several changes: - the library provides a name data structure (hicn_name_t ), which is composed of a name prefix (hicn_name_prefix_t) and a name suffix (hicn_name_suffix_t), and it has been extended to provide all support functions required for name manipulation, including common prefix computation, as required for the Longest Prefix Match (LPM)in the forwarder, in addition to Exact Prefix Match (EPM). - all code has been rewritten to use this data structure instead of having for instance the forwarder define its own name class (used to be Name and NameBitVector) the code has been refactored to minimize name allocations and copies, one remaining aspect is the difference of name storage between PIT and CS entries (respectively in the PIT entry, and in the message buffer), which causes the packet cache index to be updated when a PIT entry is converted into a CS entry. By storing the name in the PIT/CS entry everytime, we might save on this operation). - hicn-light FIB has been rewritten : code has been refactored and should now be shorter and documented; unit tests have been drafted but more would be required to cover all cases and match the algorithms to add/remove nodes, as specified in the doc. all protocol details and hICN header formats are now abstracted by the library for the forwarder (and thus header.h and  protocols/*.h have been removed from public includes, and replaced by packet.h providing protocol agnostic packet level functions, completely replacing the compat.h header that used to provide similar functions. - this works by exposing a opaque buffer to the application (a kind of socket buffer) which is used by the lib to cache the packet format and offsets of the different layers in the buffer and provider efficient operations (the packet format is either defined for packet construction, or guessed at ingress, and this structure is updated accordingly only once). Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com> Signed-off-by: Luca Muscariello <muscariello@ieee.org> Change-Id: I31e321897f85f0267fe8ba4720363c180564492f
Diffstat (limited to 'lib/src')
-rw-r--r--lib/src/CMakeLists.txt5
-rw-r--r--lib/src/base.c52
-rw-r--r--lib/src/compat.c1268
-rw-r--r--lib/src/face.c58
-rw-r--r--lib/src/mapme.c51
-rw-r--r--lib/src/name.c280
-rw-r--r--lib/src/ops.c47
-rw-r--r--lib/src/ops.h1082
-rw-r--r--lib/src/packet.c833
-rw-r--r--lib/src/protocol.h40
-rw-r--r--lib/src/protocol/ah.c204
-rw-r--r--lib/src/protocol/ah.h83
-rw-r--r--lib/src/protocol/icmp.c177
-rw-r--r--lib/src/protocol/icmp.h84
-rw-r--r--lib/src/protocol/icmprd.h72
-rw-r--r--lib/src/protocol/ipv4.c496
-rw-r--r--lib/src/protocol/ipv4.h112
-rw-r--r--lib/src/protocol/ipv6.c450
-rw-r--r--lib/src/protocol/ipv6.h86
-rw-r--r--lib/src/protocol/new.c475
-rw-r--r--lib/src/protocol/new.h95
-rw-r--r--lib/src/protocol/tcp.c457
-rw-r--r--lib/src/protocol/tcp.h165
-rw-r--r--lib/src/protocol/udp.c283
-rw-r--r--lib/src/protocol/udp.h44
-rw-r--r--lib/src/test/CMakeLists.txt6
-rw-r--r--lib/src/test/test_bitmap.cc261
-rw-r--r--lib/src/test/test_interest_manifest.cc86
-rw-r--r--lib/src/test/test_khash.cc179
-rw-r--r--lib/src/test/test_name.cc82
-rw-r--r--lib/src/test/test_new_header.cc42
-rw-r--r--lib/src/test/test_pool.cc209
-rw-r--r--lib/src/test/test_ring.cc104
-rw-r--r--lib/src/test/test_udp_header.cc65
-rw-r--r--lib/src/test/test_vector.cc254
-rw-r--r--lib/src/util/ip_address.c192
-rw-r--r--lib/src/util/pool.c1
-rw-r--r--lib/src/util/types.c56
38 files changed, 5924 insertions, 2612 deletions
diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt
index 8e81aa442..10c39fae2 100644
--- a/lib/src/CMakeLists.txt
+++ b/lib/src/CMakeLists.txt
@@ -15,13 +15,14 @@
# Source and Header files
##############################################################
list(APPEND LIBHICN_SOURCE_FILES
+ base.c
common.c
- compat.c
error.c
face.c
mapme.c
name.c
ops.c
+ packet.c
policy.c
strategy.c
protocol/ah.c
@@ -35,6 +36,7 @@ list(APPEND LIBHICN_SOURCE_FILES
util/log.c
util/pool.c
util/ring.c
+ util/types.c
util/vector.c
)
@@ -72,6 +74,7 @@ endif()
##############################################################
set(COMPILER_OPTIONS
${DEFAULT_COMPILER_OPTIONS}
+ PRIVATE "-Wno-address-of-packed-member"
)
diff --git a/lib/src/base.c b/lib/src/base.c
new file mode 100644
index 000000000..a15d55938
--- /dev/null
+++ b/lib/src/base.c
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file base.c
+ * @brief Implementation of base hICN definitions.
+ */
+
+#include <hicn/base.h>
+#include "ops.h"
+
+const char *_hicn_packet_type_str[] = {
+#define _(x) [HICN_PACKET_TYPE_##x] = #x,
+ foreach_packet_type
+#undef _
+};
+
+int
+hicn_packet_format_snprintf (char *s, size_t size, hicn_packet_format_t format)
+{
+ char *cur = s;
+ int rc;
+ for (unsigned i = 0; i < 4; i++)
+ {
+ if (i > 0)
+ {
+ rc = snprintf (cur, size - (cur - s), " %s ", "/");
+ if (rc < 0 || rc >= size - (cur - s))
+ return rc;
+ cur += rc;
+ }
+
+ rc = snprintf (cur, size - (cur - s), "%s",
+ hicn_ops_vft[format.as_u8[i]]->name);
+ if (rc < 0 || rc >= size - (cur - s))
+ return rc;
+ cur += rc;
+ }
+ return (int) (cur - s);
+}
diff --git a/lib/src/compat.c b/lib/src/compat.c
deleted file mode 100644
index cb771dbdd..000000000
--- a/lib/src/compat.c
+++ /dev/null
@@ -1,1268 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @file compat.c
- * @brief Implementation of the compatibility layer.
- */
-#ifndef _WIN32
-#include <netinet/in.h>
-#endif
-#include <string.h> // memset
-#include <stddef.h> // offsetof
-
-#include <hicn/common.h>
-#include <hicn/compat.h>
-#include <hicn/error.h>
-#include <hicn/header.h>
-#include <hicn/name.h>
-#include <hicn/ops.h>
-
-#define member_size(type, member) sizeof (((type *) 0)->member)
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
-
-#define HICN_NAME_COMPONENT_SIZE 2
-
-int
-hicn_packet_get_format (const hicn_header_t *h, hicn_format_t *format)
-{
- *format = HF_UNSPEC;
-
- switch (HICN_IP_VERSION (h))
- {
- case 4:
- switch (h->v4.ip.protocol)
- {
- case IPPROTO_TCP:
- if (h->v4.tcp.flags & AH_FLAG)
- *format = HF_INET_TCP_AH;
- else
- *format = HF_INET_TCP;
- break;
- case IPPROTO_UDP:
- if (h->v4.newhdr.flags & HICN_NEW_FLAG_SIG)
- *format = HF_INET_UDP_AH;
- else
- *format = HF_INET_UDP;
- break;
- case IPPROTO_ICMP:
- *format = HF_INET_ICMP;
- break;
- default:
- return HICN_LIB_ERROR_NOT_HICN;
- }
- break;
- case 6:
- switch (h->v6.ip.nxt)
- {
- case IPPROTO_TCP:
- if (h->v6.tcp.flags & AH_FLAG)
- *format = HF_INET6_TCP_AH;
- else
- *format = HF_INET6_TCP;
- break;
- case IPPROTO_UDP:
- if (h->v6.newhdr.flags & HICN_NEW_FLAG_SIG)
- *format = HF_INET6_UDP_AH;
- else
- *format = HF_INET6_UDP;
- break;
- case IPPROTO_ICMPV6:
- *format = HF_INET6_ICMP;
- break;
- default:
- return HICN_LIB_ERROR_NOT_HICN;
- }
- break;
- case 9:
- {
- uint8_t ah = (HICN_NEW_FLAG_SIG & h->protocol.newhdr.flags);
- *format = HF_NEW_AH * ah + (1 - ah) * HF_NEW;
- break;
- }
- default:
- return HICN_LIB_ERROR_NOT_HICN;
- }
-
- return HICN_LIB_ERROR_NONE;
-}
-
-/**
- * @brief Convert (former) hICN format into (newer) hICN type
- * @param [in] format - hICN format
- * @return hICN type, all zero'ed if type is unknown
- */
-hicn_type_t
-hicn_format_to_type (hicn_format_t format)
-{
- switch (format)
- {
- case HF_INET_TCP:
- return HICN_TYPE_IPV4_TCP;
- case HF_INET_UDP:
- return HICN_TYPE_IPV4_UDP;
- case HF_INET6_TCP:
- return HICN_TYPE_IPV6_TCP;
- case HF_INET6_UDP:
- return HICN_TYPE_IPV6_UDP;
- case HF_INET_ICMP:
- return HICN_TYPE_IPV4_ICMP;
- case HF_INET6_ICMP:
- return HICN_TYPE_IPV6_ICMP;
- case HF_NEW:
- return HICN_TYPE_NEW;
- case HF_INET_TCP_AH:
- return HICN_TYPE_IPV4_TCP_AH;
- case HF_INET_UDP_AH:
- return HICN_TYPE_IPV4_UDP_AH;
- case HF_INET6_TCP_AH:
- return HICN_TYPE_IPV6_TCP_AH;
- case HF_INET6_UDP_AH:
- return HICN_TYPE_IPV6_UDP_AH;
- case HF_INET_ICMP_AH:
- return HICN_TYPE_IPV4_ICMP_AH;
- case HF_INET6_ICMP_AH:
- return HICN_TYPE_IPV6_ICMP_AH;
- case HF_NEW_AH:
- return HICN_TYPE_NEW_AH;
- default:
- break;
- }
- return HICN_TYPE_NONE;
-}
-
-/**
- * @brief Parse hICN header and return hICN type
- * @param [in] h - hICN header
- * @param [out] format - hICN type
- * @return hICN error code
- *
- * This function is used to wrap old API calls to new ones
- */
-hicn_type_t
-hicn_header_to_type (const hicn_header_t *h)
-{
- hicn_format_t format;
- hicn_packet_get_format (h, &format);
- return hicn_format_to_type (format);
-}
-
-int
-hicn_packet_init_header (hicn_format_t format, hicn_header_t *packet)
-{
- hicn_type_t type = hicn_format_to_type (format);
-
- if (hicn_type_is_none (type))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- return hicn_ops_vft[type.l1]->init_packet_header (type, &packet->protocol);
-}
-
-int
-hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t *h)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, 0, ~0);
-}
-
-int
-hicn_packet_compute_header_checksum (hicn_format_t format, hicn_header_t *h,
- u16 init_sum)
-{
- hicn_type_t type = hicn_format_to_type (format);
- /* payload_length == 0: ignore payload */
- return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, init_sum,
- 0);
-}
-
-int
-hicn_packet_check_integrity_no_payload (hicn_format_t format, hicn_header_t *h,
- u16 init_sum)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->verify_checksums (type, &h->protocol, init_sum,
- 0);
-}
-
-int
-hicn_packet_get_header_length_from_format (hicn_format_t format,
- size_t *header_length)
-{
- *header_length = _is_ipv4 (format) * IPV4_HDRLEN;
- *header_length += _is_ipv6 (format) * IPV6_HDRLEN;
- *header_length += _is_icmp (format) * ICMP_HDRLEN;
- *header_length += _is_tcp (format) * TCP_HDRLEN;
- *header_length += _is_udp (format) * UDP_HDRLEN;
- *header_length += _is_cmpr (format) * NEW_HDRLEN;
- *header_length += _is_ah (format) * AH_HDRLEN;
-
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_get_header_length (hicn_format_t format, const hicn_header_t *h,
- size_t *header_length)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
- header_length);
-}
-
-int
-hicn_packet_get_payload_length (hicn_format_t format, const hicn_header_t *h,
- size_t *payload_length)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol,
- payload_length);
-}
-
-int
-hicn_packet_set_payload_length (hicn_format_t format, hicn_header_t *h,
- const size_t payload_length)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_payload_length (type, &h->protocol,
- payload_length);
-}
-
-int
-hicn_packet_compare (const hicn_header_t *packet1,
- const hicn_header_t *packet2)
-{
- hicn_type_t type1 = hicn_header_to_type (packet1);
- hicn_type_t type2 = hicn_header_to_type (packet2);
-
- size_t len1, len2;
- int rc;
-
- if (type1.as_u32 != type2.as_u32)
- return HICN_LIB_ERROR_UNEXPECTED;
-
- rc = hicn_ops_vft[type1.l1]->get_length (type1, &packet1->protocol, &len1);
- if (PREDICT_FALSE (rc < 0))
- return HICN_LIB_ERROR_UNEXPECTED;
-
- rc = hicn_ops_vft[type2.l1]->get_length (type2, &packet2->protocol, &len2);
- if (PREDICT_FALSE (rc < 0))
- return HICN_LIB_ERROR_UNEXPECTED;
-
- if (len1 != len2)
- return HICN_LIB_ERROR_UNEXPECTED;
-
- return memcmp ((u8 *) packet1, (u8 *) packet2, len1);
-}
-
-int
-hicn_packet_get_name (hicn_format_t format, const hicn_header_t *h,
- hicn_name_t *name, u8 is_interest)
-{
- hicn_type_t type = hicn_format_to_type (format);
-
- if (is_interest)
- return hicn_ops_vft[type.l1]->get_interest_name (type, &h->protocol, name);
- else
- return hicn_ops_vft[type.l1]->get_data_name (type, &h->protocol, name);
-}
-
-int
-hicn_packet_set_name (hicn_format_t format, hicn_header_t *h,
- const hicn_name_t *name, u8 is_interest)
-{
- hicn_type_t type = hicn_format_to_type (format);
-
- if (is_interest)
- return hicn_ops_vft[type.l1]->set_interest_name (type, &h->protocol, name);
- else
- return hicn_ops_vft[type.l1]->set_data_name (type, &h->protocol, name);
-}
-
-int
-hicn_packet_set_payload (hicn_format_t format, hicn_header_t *h,
- const u8 *payload, u16 payload_length)
-{
- hicn_type_t type = hicn_format_to_type (format);
- size_t header_length;
- int rc;
-
- rc = hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
- &header_length);
- if (rc < 0)
- return rc;
-
- memcpy ((u8 *) h + header_length, payload, payload_length);
-
- return hicn_ops_vft[type.l1]->set_payload_length (type, &h->protocol,
- payload_length);
-}
-
-int
-hicn_packet_get_payload (hicn_format_t format, const hicn_header_t *h,
- u8 **payload, size_t *payload_size, bool hard_copy)
-{
- size_t header_length, payload_length;
- int rc;
- hicn_type_t type = hicn_format_to_type (format);
-
- rc = hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol,
- &header_length);
- if (rc < 0)
- return rc;
-
- rc = hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol,
- &payload_length);
- if (rc < 0)
- return rc;
-
- if (hard_copy)
- {
- memcpy (payload, (u8 *) h + header_length, payload_length);
- }
- else
- {
- *payload = (u8 *) h + header_length;
- }
-
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_get_locator (hicn_format_t format, const hicn_header_t *h,
- ip_address_t *address, bool is_interest)
-{
- hicn_type_t type = hicn_format_to_type (format);
- if (is_interest)
- return hicn_ops_vft[type.l1]->get_interest_locator (type, &h->protocol,
- address);
- else
- return hicn_ops_vft[type.l1]->get_data_locator (type, &h->protocol,
- address);
-}
-
-int
-hicn_packet_set_locator (hicn_format_t format, hicn_header_t *h,
- const ip_address_t *address, bool is_interest)
-{
- hicn_type_t type = hicn_format_to_type (format);
- if (is_interest)
- return hicn_ops_vft[type.l1]->set_interest_locator (type, &h->protocol,
- address);
- else
- return hicn_ops_vft[type.l1]->set_data_locator (type, &h->protocol,
- address);
-}
-
-int
-hicn_packet_get_signature_size (hicn_format_t format, const hicn_header_t *h,
- size_t *bytes)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_signature_size (type, &h->protocol, bytes);
-}
-
-int
-hicn_packet_set_signature_size (hicn_format_t format, hicn_header_t *h,
- size_t bytes)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_signature_size (type, &h->protocol, bytes);
-}
-
-int
-hicn_packet_get_signature_padding (hicn_format_t format,
- const hicn_header_t *h, size_t *bytes)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_signature_padding (type, &h->protocol,
- bytes);
-}
-
-int
-hicn_packet_set_signature_padding (hicn_format_t format, hicn_header_t *h,
- size_t bytes)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_signature_padding (type, &h->protocol,
- bytes);
-}
-
-int
-hicn_packet_set_signature_timestamp (hicn_format_t format, hicn_header_t *h,
- uint64_t signature_timestamp)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_signature_timestamp (type, &h->protocol,
- signature_timestamp);
-}
-
-int
-hicn_packet_get_signature_timestamp (hicn_format_t format,
- const hicn_header_t *h,
- uint64_t *signature_timestamp)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_signature_timestamp (type, &h->protocol,
- signature_timestamp);
-}
-
-int
-hicn_packet_set_validation_algorithm (hicn_format_t format, hicn_header_t *h,
- uint8_t validation_algorithm)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_validation_algorithm (
- type, &h->protocol, validation_algorithm);
-}
-
-int
-hicn_packet_get_validation_algorithm (hicn_format_t format,
- const hicn_header_t *h,
- uint8_t *validation_algorithm)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_validation_algorithm (
- type, &h->protocol, validation_algorithm);
-}
-
-int
-hicn_packet_set_key_id (hicn_format_t format, hicn_header_t *h,
- uint8_t *key_id)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_key_id (type, &h->protocol, key_id);
-}
-
-int
-hicn_packet_get_key_id (hicn_format_t format, hicn_header_t *h,
- uint8_t **key_id, uint8_t *key_id_length)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_key_id (type, &h->protocol, key_id,
- key_id_length);
-}
-
-int
-hicn_packet_get_hoplimit (const hicn_header_t *h, u8 *hops)
-{
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *hops = h->v6.ip.hlim;
- break;
- case 4:
- *hops = h->v4.ip.ttl;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_hoplimit (hicn_header_t *h, u8 hops)
-{
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.ip.hlim = hops;
- break;
- case 4:
- h->v4.ip.ttl = hops;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_is_interest (hicn_format_t format, const hicn_header_t *h,
- int *ret)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->is_interest (type, &h->protocol, ret);
-}
-
-int
-hicn_packet_set_interest (hicn_format_t format, hicn_header_t *h)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->mark_packet_as_interest (type, &h->protocol);
-}
-
-int
-hicn_packet_set_data (hicn_format_t format, hicn_header_t *h)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->mark_packet_as_data (type, &h->protocol);
-}
-
-int
-hicn_packet_get_lifetime (hicn_format_t format, const hicn_header_t *h,
- u32 *lifetime)
-{
- hicn_type_t type = hicn_header_to_type (h);
- return hicn_ops_vft[type.l1]->get_lifetime (type, &h->protocol,
- (hicn_lifetime_t *) lifetime);
-}
-
-int
-hicn_packet_set_lifetime (hicn_format_t format, hicn_header_t *h, u32 lifetime)
-{
- hicn_type_t type = hicn_header_to_type (h);
- return hicn_ops_vft[type.l1]->set_lifetime (type, &h->protocol,
- (hicn_lifetime_t) lifetime);
-}
-
-int
-hicn_packet_get_reserved_bits (const hicn_header_t *h, u8 *reserved_bits)
-{
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *reserved_bits = (u8) (h->v6.tcp.reserved);
- break;
- case 4:
- *reserved_bits = (u8) (h->v4.tcp.reserved);
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_reserved_bits (hicn_header_t *h, const u8 reserved_bits)
-{
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.reserved = reserved_bits;
- break;
- case 4:
- h->v4.tcp.reserved = reserved_bits;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_get_payload_type (hicn_format_t format, const hicn_header_t *h,
- hicn_payload_type_t *payload_type)
-{
- hicn_type_t type = hicn_header_to_type (h);
- return hicn_ops_vft[type.l1]->get_payload_type (type, &h->protocol,
- payload_type);
-}
-
-int
-hicn_packet_set_payload_type (hicn_format_t format, hicn_header_t *h,
- hicn_payload_type_t payload_type)
-{
- hicn_type_t type = hicn_header_to_type (h);
- return hicn_ops_vft[type.l1]->set_payload_type (type, &h->protocol,
- payload_type);
-}
-
-int
-hicn_packet_set_syn (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_SYN;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_SYN;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_reset_syn (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_SYN;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_SYN;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_test_syn (hicn_format_t format, const hicn_header_t *h, bool *flag)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *flag = h->v6.tcp.flags & HICN_TCP_FLAG_SYN;
- break;
- case 4:
- *flag = h->v4.tcp.flags & HICN_TCP_FLAG_SYN;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_ack (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_ACK;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_ACK;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_reset_ack (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_ACK;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_ACK;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_test_ack (hicn_format_t format, const hicn_header_t *h, bool *flag)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *flag = h->v6.tcp.flags & HICN_TCP_FLAG_ACK;
- break;
- case 4:
- *flag = h->v4.tcp.flags & HICN_TCP_FLAG_ACK;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_rst (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_RST;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_RST;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_reset_rst (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_RST;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_RST;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_test_rst (hicn_format_t format, const hicn_header_t *h, bool *flag)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *flag = h->v6.tcp.flags & HICN_TCP_FLAG_RST;
- break;
- case 4:
- *flag = h->v4.tcp.flags & HICN_TCP_FLAG_RST;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_fin (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_FIN;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_FIN;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_reset_fin (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_FIN;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_FIN;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_test_fin (hicn_format_t format, const hicn_header_t *h, bool *flag)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *flag = h->v6.tcp.flags & HICN_TCP_FLAG_FIN;
- break;
- case 4:
- *flag = h->v4.tcp.flags & HICN_TCP_FLAG_FIN;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_ece (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_ECE;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_ECE;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_reset_ece (hicn_format_t format, hicn_header_t *h)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_ECE;
- break;
- case 4:
- h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_ECE;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_test_ece (hicn_format_t format, const hicn_header_t *h, bool *flag)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *flag = h->v6.tcp.flags & HICN_TCP_FLAG_ECE;
- break;
- case 4:
- *flag = h->v4.tcp.flags & HICN_TCP_FLAG_ECE;
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_src_port (hicn_format_t format, hicn_header_t *h, u16 src_port)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.sport = htons (src_port);
- break;
- case 4:
- h->v4.tcp.sport = htons (src_port);
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_get_src_port (hicn_format_t format, const hicn_header_t *h,
- u16 *src_port)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *src_port = ntohs (h->v6.tcp.sport);
- break;
- case 4:
- *src_port = ntohs (h->v4.tcp.sport);
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_set_dst_port (hicn_format_t format, hicn_header_t *h, u16 dst_port)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- h->v6.tcp.dport = htons (dst_port);
- break;
- case 4:
- h->v4.tcp.dport = htons (dst_port);
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_get_dst_port (hicn_format_t format, const hicn_header_t *h,
- u16 *dst_port)
-{
- if (!_is_tcp (format))
- {
- return HICN_LIB_ERROR_UNEXPECTED;
- }
-
- switch (HICN_IP_VERSION (h))
- {
- case 6:
- *dst_port = ntohs (h->v6.tcp.dport);
- break;
- case 4:
- *dst_port = ntohs (h->v4.tcp.dport);
- break;
- default:
- return HICN_LIB_ERROR_UNEXPECTED;
- }
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-hicn_packet_copy_header (hicn_format_t format, const hicn_header_t *packet,
- hicn_header_t *destination, bool copy_ah)
-{
- size_t header_length = _is_ipv4 (format) * IPV4_HDRLEN;
- header_length += _is_ipv6 (format) * IPV6_HDRLEN;
- header_length += _is_icmp (format) * ICMP_HDRLEN;
- header_length += _is_tcp (format) * TCP_HDRLEN;
- header_length += _is_ah (format) * copy_ah * AH_HDRLEN;
-
- memcpy (destination, packet, header_length);
-
- return HICN_LIB_ERROR_NONE;
-}
-
-#define _INTEREST 1
-#define _DATA 0
-
-/* Interest */
-
-int
-hicn_interest_get_name (hicn_format_t format, const hicn_header_t *interest,
- hicn_name_t *name)
-{
- return hicn_packet_get_name (format, interest, name, _INTEREST);
-}
-
-int
-hicn_interest_set_name (hicn_format_t format, hicn_header_t *interest,
- const hicn_name_t *name)
-{
- return hicn_packet_set_name (format, interest, name, _INTEREST);
-}
-
-int
-hicn_interest_get_locator (hicn_format_t format, const hicn_header_t *interest,
- ip_address_t *address)
-{
- return hicn_packet_get_locator (format, interest, address, _INTEREST);
-}
-
-int
-hicn_interest_set_locator (hicn_format_t format, hicn_header_t *interest,
- const ip_address_t *address)
-{
- return hicn_packet_set_locator (format, interest, address, _INTEREST);
-}
-
-int
-hicn_interest_compare (const hicn_header_t *interest_1,
- const hicn_header_t *interest_2)
-{
- return hicn_packet_compare (interest_1, interest_2);
-}
-
-int
-hicn_interest_get_lifetime (const hicn_header_t *interest, u32 *lifetime)
-{
- hicn_format_t format;
- int rc = hicn_packet_get_format (interest, &format);
-
- if (rc)
- return rc;
-
- return hicn_packet_get_lifetime (format, interest, lifetime);
-}
-
-int
-hicn_interest_set_lifetime (hicn_header_t *interest, u32 lifetime)
-{
- hicn_format_t format;
- int rc = hicn_packet_get_format (interest, &format);
-
- if (rc)
- return rc;
-
- return hicn_packet_set_lifetime (format, interest, lifetime);
-}
-
-int
-hicn_interest_get_header_length (hicn_format_t format,
- const hicn_header_t *interest,
- size_t *header_length)
-{
- return hicn_packet_get_header_length (format, interest, header_length);
-}
-
-int
-hicn_interest_get_payload_length (hicn_format_t format,
- const hicn_header_t *interest,
- size_t *payload_length)
-{
- return hicn_packet_get_payload_length (format, interest, payload_length);
-}
-
-int
-hicn_interest_get_payload (hicn_format_t format, const hicn_header_t *interest,
- u8 **payload, size_t *payload_size, bool hard_copy)
-{
- return hicn_packet_get_payload (format, interest, payload, payload_size,
- hard_copy);
-}
-
-int
-hicn_interest_set_payload (hicn_format_t format, hicn_header_t *interest,
- const u8 *payload, size_t payload_length)
-{
- return hicn_packet_set_payload (format, interest, payload,
- (u16) payload_length);
-}
-
-int
-hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t *packet)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->reset_interest_for_hash (type,
- &packet->protocol);
-}
-
-/* Data */
-
-int
-hicn_data_get_name (hicn_format_t format, const hicn_header_t *data,
- hicn_name_t *name)
-{
- return hicn_packet_get_name (format, data, name, _DATA);
-}
-
-int
-hicn_data_set_name (hicn_format_t format, hicn_header_t *data,
- const hicn_name_t *name)
-{
- return hicn_packet_set_name (format, data, name, _DATA);
-}
-
-int
-hicn_data_get_locator (hicn_format_t format, const hicn_header_t *data,
- ip_address_t *address)
-{
- return hicn_packet_get_locator (format, data, address, _DATA);
-}
-
-int
-hicn_data_set_locator (hicn_format_t format, hicn_header_t *data,
- const ip_address_t *address)
-{
- return hicn_packet_set_locator (format, data, address, _DATA);
-}
-
-int
-hicn_data_compare (const hicn_header_t *data_1, const hicn_header_t *data_2)
-{
- return hicn_packet_compare (data_1, data_2);
-}
-
-int
-hicn_data_get_expiry_time (const hicn_header_t *data, u32 *expiry_time)
-{
- hicn_format_t format;
- int rc = hicn_packet_get_format (data, &format);
-
- if (rc)
- return rc;
-
- return hicn_packet_get_lifetime (format, data, expiry_time);
-}
-
-int
-hicn_data_set_expiry_time (hicn_header_t *data, u32 expiry_time)
-{
- hicn_format_t format;
- int rc = hicn_packet_get_format (data, &format);
-
- if (rc)
- return rc;
-
- return hicn_packet_set_lifetime (format, data,
- (hicn_lifetime_t) expiry_time);
-}
-
-int
-hicn_data_get_header_length (hicn_format_t format, hicn_header_t *data,
- size_t *header_length)
-{
- return hicn_packet_get_header_length (format, data, header_length);
-}
-
-int
-hicn_data_get_payload_length (hicn_format_t format, const hicn_header_t *data,
- size_t *payload_length)
-{
- return hicn_packet_get_payload_length (format, data, payload_length);
-}
-
-int
-hicn_data_get_path_label (const hicn_header_t *data, u32 *path_label)
-{
- hicn_type_t type = hicn_header_to_type (data);
- return hicn_ops_vft[type.l1]->get_data_pathlabel (type, &data->protocol,
- path_label);
-}
-
-int
-hicn_data_set_path_label (hicn_header_t *data, u32 path_label)
-{
- hicn_type_t type = hicn_header_to_type (data);
- return hicn_ops_vft[type.l1]->set_data_pathlabel (type, &data->protocol,
- path_label);
-}
-
-int
-hicn_data_set_payload (hicn_format_t format, hicn_header_t *data,
- const u8 *payload, size_t payload_length)
-{
- return hicn_packet_set_payload (format, data, payload, (u16) payload_length);
-}
-
-int
-hicn_data_get_payload (hicn_format_t format, const hicn_header_t *data,
- u8 **payload, size_t *payload_size, bool hard_copy)
-{
- return hicn_packet_get_payload (format, data, payload, payload_size,
- hard_copy);
-}
-
-int
-hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t *packet)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->reset_data_for_hash (type, &packet->protocol);
-}
-
-int
-hicn_data_is_last (hicn_format_t format, hicn_header_t *h, int *is_last)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->is_last_data (type, &h->protocol, is_last);
-}
-
-int
-hicn_data_set_last (hicn_format_t format, hicn_header_t *h)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->set_last_data (type, &h->protocol);
-}
-
-int
-hicn_packet_get_signature (hicn_format_t format, hicn_header_t *packet,
- uint8_t **sign_buf)
-{
- hicn_type_t type = hicn_format_to_type (format);
- return hicn_ops_vft[type.l1]->get_signature (type, &packet->protocol,
- sign_buf);
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/lib/src/face.c b/lib/src/face.c
index 46b36e8cd..832cd0936 100644
--- a/lib/src/face.c
+++ b/lib/src/face.c
@@ -142,6 +142,12 @@ netdevice_cmp (const netdevice_t *nd1, const netdevice_t *nd2)
return (nd1->index - nd2->index);
}
+bool
+netdevice_is_empty (const netdevice_t *netdevice)
+{
+ return (netdevice->index != 0) || (netdevice->name[0] != '\0');
+}
+
/* Face state */
const char *_face_state_str[] = {
@@ -181,8 +187,8 @@ face_initialize (face_t *face)
int
face_initialize_udp (face_t *face, const char *interface_name,
- const ip_address_t *local_addr, u16 local_port,
- const ip_address_t *remote_addr, u16 remote_port,
+ const hicn_ip_address_t *local_addr, u16 local_port,
+ const hicn_ip_address_t *remote_addr, u16 remote_port,
int family)
{
if (!local_addr)
@@ -264,9 +270,10 @@ face_create ()
}
face_t *
-face_create_udp (const char *interface_name, const ip_address_t *local_addr,
- u16 local_port, const ip_address_t *remote_addr,
- u16 remote_port, int family)
+face_create_udp (const char *interface_name,
+ const hicn_ip_address_t *local_addr, u16 local_port,
+ const hicn_ip_address_t *remote_addr, u16 remote_port,
+ int family)
{
face_t *face = face_create ();
if (face_initialize_udp (face, interface_name, local_addr, local_port,
@@ -336,11 +343,11 @@ face_cmp (const face_t *f1, const face_t *f2)
switch (f1->type)
{
case FACE_TYPE_HICN:
- ret = ip_address_cmp (&f1->local_addr, &f2->local_addr, f1->family);
+ ret = hicn_ip_address_cmp (&f1->local_addr, &f2->local_addr);
if (ret != 0)
return ret;
- ret = ip_address_cmp (&f1->remote_addr, &f2->remote_addr, f1->family);
+ ret = hicn_ip_address_cmp (&f1->remote_addr, &f2->remote_addr);
if (ret != 0)
return ret;
@@ -348,7 +355,7 @@ face_cmp (const face_t *f1, const face_t *f2)
case FACE_TYPE_TCP:
case FACE_TYPE_UDP:
- ret = ip_address_cmp (&f1->local_addr, &f2->local_addr, f1->family);
+ ret = hicn_ip_address_cmp (&f1->local_addr, &f2->local_addr);
if (ret != 0)
return ret;
@@ -356,7 +363,7 @@ face_cmp (const face_t *f1, const face_t *f2)
if (ret != 0)
return ret;
- ret = ip_address_cmp (&f1->remote_addr, &f2->remote_addr, f1->family);
+ ret = hicn_ip_address_cmp (&f1->remote_addr, &f2->remote_addr);
if (ret != 0)
return ret;
@@ -376,19 +383,24 @@ face_cmp (const face_t *f1, const face_t *f2)
size_t
face_snprintf (char *s, size_t size, const face_t *face)
{
+ char local[MAXSZ_IP_ADDRESS];
+ char remote[MAXSZ_IP_ADDRESS];
+ char tags[MAXSZ_POLICY_TAGS];
+
+ if (!hicn_ip_address_match_family (&face->local_addr, face->family))
+ return 0;
+ if (!hicn_ip_address_match_family (&face->remote_addr, face->family))
+ return 0;
+
+ hicn_ip_address_snprintf (local, MAXSZ_IP_ADDRESS, &face->local_addr);
+ hicn_ip_address_snprintf (remote, MAXSZ_IP_ADDRESS, &face->remote_addr);
+ policy_tags_snprintf (tags, MAXSZ_POLICY_TAGS, face->tags);
+
switch (face->type)
{
case FACE_TYPE_HICN:
{
- char local[MAXSZ_IP_ADDRESS];
- char remote[MAXSZ_IP_ADDRESS];
- char tags[MAXSZ_POLICY_TAGS];
-
- ip_address_snprintf (local, MAXSZ_IP_ADDRESS, &face->local_addr,
- face->family);
- ip_address_snprintf (remote, MAXSZ_IP_ADDRESS, &face->remote_addr,
- face->family);
- policy_tags_snprintf (tags, MAXSZ_POLICY_TAGS, face->tags);
+
return snprintf (s, size, "%s [%s -> %s] [%s]",
face_type_str (face->type), local, remote, tags);
}
@@ -396,16 +408,6 @@ face_snprintf (char *s, size_t size, const face_t *face)
case FACE_TYPE_TCP:
case FACE_TYPE_UDP:
{
- char local[MAXSZ_IP_ADDRESS];
- char remote[MAXSZ_IP_ADDRESS];
- char tags[MAXSZ_POLICY_TAGS];
-
- ip_address_snprintf (local, MAXSZ_IP_ADDRESS, &face->local_addr,
- face->family);
- ip_address_snprintf (remote, MAXSZ_IP_ADDRESS, &face->remote_addr,
- face->family);
- policy_tags_snprintf (tags, MAXSZ_POLICY_TAGS, face->tags);
-
return snprintf (s, size, "%s [%s:%d -> %s:%d] [%s]",
face_type_str (face->type), local, face->local_port,
remote, face->remote_port, tags);
diff --git a/lib/src/mapme.c b/lib/src/mapme.c
index b8e8eaed2..3f864e768 100644
--- a/lib/src/mapme.c
+++ b/lib/src/mapme.c
@@ -22,8 +22,44 @@
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/protocol/ipv4.h>
-#include <hicn/protocol/ipv6.h>
+#include "protocol/ipv4.h"
+#include "protocol/ipv6.h"
+#include "protocol/icmprd.h"
+
+/** @brief MAP-Me packet header for IPv4 */
+typedef struct
+{
+ _ipv4_header_t ip;
+ _icmprd4_header_t icmp_rd;
+ seq_t seq;
+ u8 len;
+ u8 _pad[3];
+} hicn_mapme_v4_header_t;
+
+/** @brief MAP-Me packet header for IPv6 */
+typedef struct
+{
+ _ipv6_header_t ip;
+ _icmprd_header_t icmp_rd;
+ seq_t seq;
+ u8 len;
+ u8 _pad[3];
+} hicn_mapme_v6_header_t;
+
+/** @brief MAP-Me packet header (IP version agnostic) */
+typedef union
+{
+ hicn_mapme_v4_header_t v4;
+ hicn_mapme_v6_header_t v6;
+} hicn_mapme_header_t;
+
+#define HICN_MAPME_V4_HDRLEN sizeof (hicn_mapme_v4_header_t)
+#define HICN_MAPME_V6_HDRLEN sizeof (hicn_mapme_v6_header_t)
+
+static_assert (EXPECTED_MAPME_V4_HDRLEN == HICN_MAPME_V4_HDRLEN,
+ "Size of MAPME_V4 struct does not match its expected size.");
+static_assert (EXPECTED_MAPME_V6_HDRLEN == HICN_MAPME_V6_HDRLEN,
+ "Size of MAPME_V6 struct does not match its expected size.");
size_t
hicn_mapme_v4_create_packet (u8 *buf, const hicn_prefix_t *prefix,
@@ -96,7 +132,7 @@ hicn_mapme_create_packet (u8 *buf, const hicn_prefix_t *prefix,
const mapme_params_t *params)
{
/* We currently ignore subsequent protocol definitions */
- if (PREDICT_TRUE (params->protocol == IPPROTO_IPV6))
+ if (HICN_EXPECT_TRUE (params->protocol == IPPROTO_IPV6))
return hicn_mapme_v6_create_packet (buf, prefix, params);
else
return hicn_mapme_v4_create_packet (buf, prefix, params);
@@ -105,7 +141,7 @@ hicn_mapme_create_packet (u8 *buf, const hicn_prefix_t *prefix,
size_t
hicn_mapme_v4_create_ack (u8 *buf, const mapme_params_t *params)
{
- ip4_address_t tmp; // tmp storage for swapping IP addresses for ACK
+ ipv4_address_t tmp; // tmp storage for swapping IP addresses for ACK
hicn_mapme_v4_header_t *mh = (hicn_mapme_v4_header_t *) buf;
tmp = mh->ip.daddr;
@@ -121,7 +157,7 @@ hicn_mapme_v4_create_ack (u8 *buf, const mapme_params_t *params)
size_t
hicn_mapme_v6_create_ack (u8 *buf, const mapme_params_t *params)
{
- ip6_address_t tmp; // tmp storage for swapping IP addresses for ACK
+ ipv6_address_t tmp; // tmp storage for swapping IP addresses for ACK
hicn_mapme_v6_header_t *mh = (hicn_mapme_v6_header_t *) buf;
tmp = mh->ip.daddr;
@@ -138,7 +174,7 @@ size_t
hicn_mapme_create_ack (u8 *buf, const mapme_params_t *params)
{
/* We currently ignore subsequent protocol definitions */
- if (PREDICT_TRUE (params->protocol == IPPROTO_IPV6))
+ if (HICN_EXPECT_TRUE (params->protocol == IPPROTO_IPV6))
return hicn_mapme_v6_create_ack (buf, params);
else
return hicn_mapme_v4_create_ack (buf, params);
@@ -205,8 +241,9 @@ hicn_mapme_parse_packet (const u8 *packet, hicn_prefix_t *prefix,
case 6:
return hicn_mapme_v6_parse_packet (packet, prefix, params);
default:
- return HICN_LIB_ERROR_UNEXPECTED;
+ break;
}
+ return HICN_LIB_ERROR_UNEXPECTED;
}
/*
diff --git a/lib/src/name.c b/lib/src/name.c
index 3bdcbbdb4..04c48cb4d 100644
--- a/lib/src/name.c
+++ b/lib/src/name.c
@@ -31,6 +31,8 @@
#include <hicn/name.h>
#include <hicn/util/sstrncpy.h>
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
int
hicn_name_create (const char *ip_address, u32 id, hicn_name_t *name)
{
@@ -55,11 +57,20 @@ hicn_name_create (const char *ip_address, u32 id, hicn_name_t *name)
}
int
-hicn_name_create_from_ip_prefix (const ip_prefix_t *prefix, u32 id,
+hicn_name_create_from_ip_address (const hicn_ip_address_t ip_address,
+ u32 suffix, hicn_name_t *name)
+{
+ name->prefix = ip_address;
+ name->suffix = suffix;
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_name_create_from_ip_prefix (const hicn_ip_prefix_t *prefix, u32 id,
hicn_name_t *name)
{
- name->prefix.v6.as_u64[0] = prefix->address.v6.as_u64[0];
- name->prefix.v6.as_u64[1] = prefix->address.v6.as_u64[1];
+ name->prefix = prefix->address;
name->suffix = id;
return HICN_LIB_ERROR_NONE;
@@ -79,15 +90,15 @@ hicn_name_compare (const hicn_name_t *name_1, const hicn_name_t *name_2,
return ret;
}
-int
-hicn_name_hash (const hicn_name_t *name, u32 *hash, bool consider_suffix)
+uint32_t
+_hicn_name_get_hash (const hicn_name_t *name, bool consider_suffix)
{
- *hash = hash32 (&name->prefix, sizeof (name->prefix));
+ uint32_t hash = hash32 (&name->prefix, sizeof (name->prefix));
if (consider_suffix)
- *hash = cumulative_hash32 (&name->suffix, sizeof (name->suffix), *hash);
+ hash = cumulative_hash32 (&name->suffix, sizeof (name->suffix), hash);
- return HICN_LIB_ERROR_NONE;
+ return hash;
}
int
@@ -116,9 +127,9 @@ hicn_name_copy_prefix_to_destination (u8 *dst, const hicn_name_t *name)
}
int
-hicn_name_set_seq_number (hicn_name_t *name, u32 seq_number)
+hicn_name_set_suffix (hicn_name_t *name, hicn_name_suffix_t suffix)
{
- name->suffix = seq_number;
+ name->suffix = suffix;
return HICN_LIB_ERROR_NONE;
}
@@ -149,7 +160,7 @@ hicn_name_to_sockaddr_address (const hicn_name_t *name,
}
int
-hicn_name_to_ip_prefix (const hicn_name_t *name, ip_prefix_t *prefix)
+hicn_name_to_hicn_ip_prefix (const hicn_name_t *name, hicn_ip_prefix_t *prefix)
{
int family, rc;
rc = hicn_name_get_family (name, &family);
@@ -211,24 +222,247 @@ hicn_name_get_family (const hicn_name_t *name, int *family)
return HICN_LIB_ERROR_NONE;
}
+bool
+hicn_name_is_v4 (const hicn_name_t *name)
+{
+ return _is_inet4 (name);
+}
+
int
-hicn_prefix_create_from_ip_prefix (const ip_prefix_t *ip_prefix,
+hicn_name_snprintf (char *s, size_t size, const hicn_name_t *name)
+{
+ int n, rc;
+ n = hicn_ip_address_snprintf (s, size, &name->prefix);
+ if (n < 0 || n >= size)
+ return n;
+ rc = snprintf (s + n, size - n, "|%d", name->suffix);
+ if (rc < 0)
+ return rc;
+ return rc + n;
+}
+
+int
+hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix,
hicn_prefix_t *prefix)
{
- switch (ip_prefix->family)
+ 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);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_name_cmp (const hicn_name_t *n1, const hicn_name_t *n2)
+{
+ int rc = hicn_ip_address_cmp (&n1->prefix, &n2->prefix);
+ if (rc != 0)
+ return rc;
+ return n2->suffix - n1->suffix;
+}
+
+bool
+hicn_name_equals (const hicn_name_t *n1, const hicn_name_t *n2)
+{
+ return (hicn_name_cmp (n1, n2) == 0);
+}
+
+int
+hicn_prefix_create_from_ip_address_len (const hicn_ip_address_t *ip_address,
+ uint8_t len, hicn_prefix_t *prefix)
+{
+ prefix->name = *ip_address;
+ prefix->len = len;
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+hicn_prefix_t *
+hicn_prefix_dup (const hicn_prefix_t *prefix)
+{
+ hicn_prefix_t *copy = malloc (sizeof (hicn_prefix_t));
+ if (!copy)
+ goto ERR_MALLOC;
+ if (hicn_prefix_copy (copy, prefix) < 0)
+ goto ERR_COPY;
+ return copy;
+
+ERR_COPY:
+ free (copy);
+ERR_MALLOC:
+ return NULL;
+}
+
+int
+hicn_prefix_copy (hicn_prefix_t *dst, const hicn_prefix_t *src)
+{
+ dst->name = src->name;
+ dst->len = src->len;
+ return 0;
+}
+
+bool
+hicn_prefix_is_v4 (const hicn_prefix_t *prefix)
+{
+ return hicn_ip_address_is_v4 (&prefix->name);
+}
+
+/*
+ * The ip address is in network byte order (big endian, msb last) in
+ * hicn_{prefix,name}_t, as in ip_address_t which builds upon struct in*_addr,
+ * 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.
+ */
+
+uint64_t
+_log2_nbo (uint64_t val)
+{
+ assert (val != 0); /* There is at least 1 bit set (network byte order) */
+
+ 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;
+
+ /* Val now contains the byte with at last 1 bit set (host bit order) */
+ if (val & 0xF0)
{
- case AF_INET:
- prefix->name.v4.as_u32 = ip_prefix->address.v4.as_u32;
- break;
- case AF_INET6:
- prefix->name.v6.as_u64[0] = ip_prefix->address.v6.as_u64[0];
- prefix->name.v6.as_u64[1] = ip_prefix->address.v6.as_u64[1];
- break;
- default:
- return HICN_LIB_ERROR_INVALID_IP_ADDRESS;
+ val = val >> 4;
+ result = result | 4;
}
- prefix->len = (u8) (ip_prefix->len);
+ if (val & 0xC)
+ {
+ val = val >> 2;
+ result = result | 2;
+ }
+ if (val & 0x2)
+ {
+ val = val >> 1;
+ result = result | 1;
+ }
+
+ return result;
+}
+
+uint32_t
+hicn_prefix_lpm (const hicn_prefix_t *p1, const hicn_prefix_t *p2)
+{
+ uint32_t prefix_len = 0;
+ /* Test each block of 64 bits as a whole */
+ for (unsigned i = 0; i < 2; i++)
+ {
+
+ /* Check for differences in the two u64 */
+ uint64_t diff = p1->name.v6.as_u64[i] ^ p2->name.v6.as_u64[i];
+ if (diff)
+ {
+ /*
+ * 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;
+ }
+ prefix_len += 8 * sizeof (uint64_t);
+ }
+
+ /* Bound the returned prefix length by the length of all input */
+ return MIN (prefix_len,
+ MIN (hicn_prefix_get_len (p1), hicn_prefix_get_len (p2)));
+}
+
+void
+hicn_prefix_clear (hicn_prefix_t *prefix, uint8_t start_from)
+{
+ uint8_t *buffer = prefix->name.v6.as_u8;
+
+ /* Compute the offset of the byte from which to clear the name... */
+ uint8_t offset = start_from / 8;
+ if (hicn_prefix_is_v4 (prefix))
+ offset += IP_ADDRESS_V4_OFFSET_LEN; /* Ignore padding */
+ /* ... and the position of the first bit to clear */
+ uint8_t pos = start_from % 8;
+
+ /* Mask to clear specific bits at offset...
+ * 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);
+ /* ... then fully clear remaining bytes */
+ for (uint8_t i = offset + 1; i < HICN_PREFIX_MAX_LEN; i++)
+ buffer[i] = 0;
+}
+
+void
+hicn_prefix_truncate (hicn_prefix_t *prefix, uint8_t len)
+{
+ hicn_prefix_clear (prefix, len);
+ prefix->len = len;
+}
+
+int
+hicn_prefix_cmp (const hicn_prefix_t *p1, const hicn_prefix_t *p2)
+{
+ if (p1->len != p2->len)
+ return p2->len - p1->len;
+ return hicn_ip_address_cmp (&p1->name, &p2->name);
+}
+
+bool
+hicn_prefix_equals (const hicn_prefix_t *p1, const hicn_prefix_t *p2)
+{
+ return hicn_prefix_cmp (p1, p2) == 0;
+}
+
+int
+hicn_prefix_snprintf (char *s, size_t size, const hicn_prefix_t *prefix)
+{
+ hicn_ip_prefix_t ip_prefix = { .family =
+ hicn_ip_address_get_family (&prefix->name),
+ .address = prefix->name,
+ .len = prefix->len };
+ return hicn_ip_prefix_snprintf (s, size, &ip_prefix);
+}
+
+uint8_t
+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);
+}
+
+int
+hicn_prefix_get_ip_prefix (const hicn_prefix_t *prefix,
+ hicn_ip_prefix_t *ip_prefix)
+{
+ *ip_prefix =
+ (hicn_ip_prefix_t){ .family = hicn_ip_address_get_family (&prefix->name),
+ .address = prefix->name,
+ .len = prefix->len };
return HICN_LIB_ERROR_NONE;
}
diff --git a/lib/src/ops.c b/lib/src/ops.c
index 20362d69d..0174a3902 100644
--- a/lib/src/ops.c
+++ b/lib/src/ops.c
@@ -22,8 +22,9 @@
#include <netinet/in.h>
#endif
#include <stdlib.h>
-#include <hicn/ops.h>
-#include <hicn/header.h>
+
+#include "ops.h"
+#include "protocol.h"
extern const hicn_ops_t hicn_ops_ipv4;
extern const hicn_ops_t hicn_ops_icmp;
@@ -34,16 +35,22 @@ extern const hicn_ops_t hicn_ops_new;
extern const hicn_ops_t hicn_ops_ah;
/* Declare empty operations (terminates recursion on protocol layers) */
-DECLARE_init_packet_header (none, NONE);
+
+int
+none_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
+{
+ pkbuf->payload = pkbuf->len;
+ return HICN_LIB_ERROR_NONE;
+}
+
DECLARE_get_interest_locator (none, NONE);
DECLARE_set_interest_locator (none, NONE);
DECLARE_get_interest_name (none, NONE);
DECLARE_set_interest_name (none, NONE);
DECLARE_get_interest_name_suffix (none, NONE);
DECLARE_set_interest_name_suffix (none, NONE);
-DECLARE_is_interest (none, NONE);
-DECLARE_mark_packet_as_interest (none, NONE);
-DECLARE_mark_packet_as_data (none, NONE);
+DECLARE_get_type (none, NONE);
+DECLARE_set_type (none, NONE);
DECLARE_reset_interest_for_hash (none, NONE);
DECLARE_get_data_locator (none, NONE);
DECLARE_set_data_locator (none, NONE);
@@ -51,25 +58,18 @@ DECLARE_get_data_name (none, NONE);
DECLARE_set_data_name (none, NONE);
DECLARE_get_data_name_suffix (none, NONE);
DECLARE_set_data_name_suffix (none, NONE);
-DECLARE_get_data_pathlabel (none, NONE);
-DECLARE_set_data_pathlabel (none, NONE);
-DECLARE_update_data_pathlabel (none, NONE);
+DECLARE_get_data_path_label (none, NONE);
+DECLARE_set_data_path_label (none, NONE);
+DECLARE_update_data_path_label (none, NONE);
DECLARE_reset_data_for_hash (none, NONE);
DECLARE_get_lifetime (none, NONE);
DECLARE_set_lifetime (none, NONE);
-DECLARE_get_source_port (none, NONE);
-DECLARE_get_dest_port (none, NONE);
-DECLARE_set_source_port (none, NONE);
-DECLARE_set_dest_port (none, NONE);
DECLARE_update_checksums (none, NONE);
+DECLARE_update_checksums_incremental (none, NONE);
DECLARE_verify_checksums (none, NONE);
DECLARE_rewrite_interest (none, NONE);
DECLARE_rewrite_data (none, NONE);
-DECLARE_get_length (none, NONE);
-DECLARE_get_header_length (none, NONE);
-DECLARE_get_current_header_length (none, NONE);
-DECLARE_get_payload_length (none, NONE);
-DECLARE_set_payload_length (none, NONE);
+DECLARE_set_payload_len (none, NONE);
DECLARE_get_payload_type (none, NONE);
DECLARE_set_payload_type (none, NONE);
DECLARE_get_signature_size (none, NONE);
@@ -81,11 +81,18 @@ DECLARE_get_validation_algorithm (none, NONE);
DECLARE_set_key_id (none, NONE);
DECLARE_get_key_id (none, NONE);
DECLARE_get_signature (none, NONE);
+DECLARE_has_signature (none, NONE);
DECLARE_get_signature_padding (none, NONE);
DECLARE_set_signature_padding (none, NONE);
DECLARE_is_last_data (none, NONE);
DECLARE_set_last_data (none, NONE);
-DECLARE_HICN_OPS (none);
+DECLARE_get_ttl (none, NONE);
+DECLARE_set_ttl (none, NONE);
+DECLARE_get_src_port (none, NONE);
+DECLARE_set_src_port (none, NONE);
+DECLARE_get_dst_port (none, NONE);
+DECLARE_set_dst_port (none, NONE);
+DECLARE_HICN_OPS (none, 0);
/**
* @brief Virtual function table for packet operations
@@ -99,8 +106,8 @@ const hicn_ops_t *const hicn_ops_vft[] = {
/* 41 */[IPPROTO_IPV6] = &hicn_ops_ipv6,
/* 51 */[IPPROTO_AH] = &hicn_ops_ah,
/* 58 */[IPPROTO_ICMPV6] = &hicn_ops_icmp,
+ /* 59 */[IPPROTO_NONE] = &hicn_ops_none,
/* 98 */[IPPROTO_ENCAP] = &hicn_ops_new,
- [IPPROTO_NONE] = &hicn_ops_none,
};
/*
diff --git a/lib/src/ops.h b/lib/src/ops.h
new file mode 100644
index 000000000..886d75cd5
--- /dev/null
+++ b/lib/src/ops.h
@@ -0,0 +1,1082 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file base.h
+ * @brief Protocol-independent packet operations
+ */
+
+#ifndef HICN_OPS_H
+#define HICN_OPS_H
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <hicn/base.h>
+#include <hicn/error.h>
+#include <hicn/name.h>
+#include <hicn/packet.h> // HICN_OPAQUE_LEN
+#include <hicn/util/ip_address.h>
+
+#include "protocol.h"
+
+/*
+ * In order to provide fast lookup and accelerate packet operations, we allow
+ * ourselves to use a header cache structure under the responsibility of the
+ * caller, and that can be associated to each packet. This structure is exposed
+ * as a opaque pointer.
+ */
+
+/*
+ * hICN operations on packets
+ *
+ * All prototypes take an hicn_type_t parameter as their first argument, as
+ * this decides the sequence of protocols that are being used by the different
+ * operations.
+ */
+
+typedef struct hicn_ops_s
+{
+ const char *name;
+
+ size_t header_len;
+
+ /**
+ * @brief Initialize the headers of the hicn packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ */
+ int (*init_packet_header) (hicn_packet_buffer_t *pkbuf, size_t pos);
+
+ /**
+ * @brief Retrieves an Interest locator
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] ip_address - Retrieved locator
+ * @return hICN error code
+ */
+ int (*get_interest_locator) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos,
+ hicn_ip_address_t *ip_address);
+
+ /**
+ * @brief Sets an Interest locator
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] ip_address - Locator to set
+ * @return hICN error code
+ */
+ int (*set_interest_locator) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address);
+
+ /**
+ * @brief Retrieves an Interest name
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] name - Retrieved name
+ * @return hICN error code
+ */
+ int (*get_interest_name) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos, hicn_name_t *name);
+
+ /**
+ * @brief Sets an Interest name
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] name - Name to set
+ * @return hICN error code
+ */
+ int (*set_interest_name) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_name_t *name);
+
+ /**
+ * @brief Retrieves an Interest name suffix
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] suffix - Retrieved name suffix
+ * @return hICN error code
+ */
+ int (*get_interest_name_suffix) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos,
+ hicn_name_suffix_t *suffix);
+
+ /**
+ * @brief Sets an Interest name suffix
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] suffix - Name suffix to set
+ * @return hICN error code
+ */
+ int (*set_interest_name_suffix) (const hicn_packet_buffer_t *pkbuf,
+ size_t pos,
+ const hicn_name_suffix_t *suffix);
+
+ /**
+ * @brief Get packet type
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Position within the network layers
+ * @param [out] type - Packet type
+ * @return hICN error code
+ */
+ int (*get_type) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type);
+
+ /**
+ * @brief Set flag to mark current packet as interest
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Position within the network layers
+ * @param [in] type - Packet type
+ * @return hICN error code
+ */
+ int (*set_type) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type);
+
+ /**
+ * @brief Clear the necessary Interest fields in order to hash it
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @return hICN error code
+ */
+ int (*reset_interest_for_hash) (hicn_packet_buffer_t *pkbuf, size_t pos);
+
+ /**
+ * @brief Retrieves a Data locator
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] ip_address - Retrieved locator
+ * @return hICN error code
+ */
+ int (*get_data_locator) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_ip_address_t *ip_address);
+
+ /**
+ * @brief Sets a Data locator
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] ip_address - Locator to set
+ * @return hICN error code
+ */
+ int (*set_data_locator) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address);
+
+ /**
+ * @brief Retrieves a Data name
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] name - Retrieved name
+ * @return hICN error code
+ */
+ int (*get_data_name) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_name_t *name);
+
+ /**
+ * @brief Sets a Data name
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] name - Name to set
+ * @return hICN error code
+ */
+ int (*set_data_name) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_name_t *name);
+
+ /**
+ * @brief Retrieves a Data name suffix
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] suffix - Retrieved name suffix
+ * @return hICN error code
+ */
+ int (*get_data_name_suffix) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos, hicn_name_suffix_t *suffix);
+
+ /**
+ * @brief Sets a Data name suffix
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] suffix - Name suffix to set
+ * @return hICN error code
+ */
+ int (*set_data_name_suffix) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_name_suffix_t *suffix);
+
+ /**
+ * @brief Retrieves a Data path_label
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [out] path_label - Retrieved path_label
+ * @return hICN error code
+ */
+ int (*get_data_path_label) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos, hicn_path_label_t *path_label);
+
+ /**
+ * @brief Sets a Data path_label
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] path_label - Pathlabel to set
+ * @return hICN error code
+ */
+ int (*set_data_path_label) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_path_label_t path_label);
+
+ /**
+ * @brief Update a Data path_label with a new face identifier
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] path_label - Face identifier used to update path_label
+ * @return hICN error code
+ */
+ int (*update_data_path_label) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_faceid_t face_id);
+
+ /**
+ * @brief Clear the necessary Data fields in order to hash it
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @return hICN error code
+ */
+ int (*reset_data_for_hash) (hicn_packet_buffer_t *pkbuf, size_t pos);
+
+ /**
+ * @brief Retrieves an Interest or Data lifetime
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] path_label - Retrieved lifetime
+ * @return hICN error code
+ */
+ int (*get_lifetime) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_lifetime_t *lifetime);
+
+ /**
+ * @brief Sets an Interest or Data lifetime
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] path_label - Lifetime to set
+ * @return hICN error code
+ */
+ int (*set_lifetime) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_lifetime_t lifetime);
+
+ /**
+ * @brief Update all checksums in packet headers
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] partial_csum - Partial checksum (set to 0, used internally to
+ * carry intermediate values from IP pseudo-header)
+ * @param [in] payload_len - Payload len (can be set to ~0, retrieved
+ * and used internally to carry payload len across protocol headers)
+ * @return hICN error code
+ *
+ * Payload len is initialized during the initial steps (eg. IP) if not
+ * provided (value is ~0), and not ignored (value is 0).
+ */
+ int (*update_checksums) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len);
+
+ /**
+ * @brief Update all checksums in packet headers
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] old_val - Pointer to the old value
+ * @param [in] new_val - Pointer to the new value
+ * @param [in] size - Size of the changed value
+ * @param [in] skip_first - Skip the first protocol (ignore IP checksum)
+ * @return hICN error code
+ */
+ int (*update_checksums_incremental) (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first);
+
+ /**
+ * @brief Validate all checksums in packet headers
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] partial_csum - Partial checksum, or zero if no partial
+ * checksum available
+ * @param [in] payload_len - Payload len (can be set to ~0, retrieved
+ * and used internally to carry payload len across protocol headers)
+ * @return hICN error code
+ */
+ int (*verify_checksums) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ u16 partial_csum, size_t payload_len);
+
+ /**
+ * @brief Rewrite an Interest packet header (locator)
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] addr_new - New locator
+ * @param [in] addr_old - Old locator (set to NULL, used internally to
+ * compute incremental checksums)
+ * @return hICN error code
+ */
+ int (*rewrite_interest) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old);
+
+ /**
+ * @brief Rewrite a Data packet header (locator + path_label)
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @param [in] addr_new - New locator
+ * @param [in] addr_old - Old locator (set to NULL, used internally to
+ * compute incremental checksums)
+ * @param [in] face_id - Face identifier used to update path_label
+ * @param [in] reset_pl - If not zero, reset the current path_label
+ * before update it
+ * @return hICN error code
+ */
+ int (*rewrite_data) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old,
+ const hicn_faceid_t face_id, u8 reset_pl);
+
+ /**
+ * @brief Return the packet len
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @parma [out] len - Returned packet len
+ * @return hICN error code
+ */
+ int (*get_len) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ size_t *len);
+
+ /**
+ * @brief Return the current packet header len
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @parma [out] header_len - Returned packet current header len
+ * @return hICN error code
+ */
+ int (*get_current_header_len) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos, size_t *header_len);
+
+ /**
+ * @brief Sets the packet paylaod len
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Depth in the header stack
+ * @parma [out] payload_len - Payload len to set
+ * @return hICN error code
+ */
+ int (*set_payload_len) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t payload_len);
+
+ /**
+ * @brief Retrieves an Interest or Data signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] signature_size - Retrieved signature size
+ * @return hICN error code
+ */
+ int (*get_signature_size) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos, size_t *signature_size);
+
+ /**
+ * @brief Sets an Interest or Data signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] signature_size - Signature size to set
+ * @return hICN error code
+ */
+ int (*set_signature_size) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t signature_size);
+
+ /**
+ * @brief Sets an Interest or Data signature padding between maximum size and
+ * real size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] signature_size - Signature size to set
+ * @return hICN error code
+ */
+ int (*set_signature_padding) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t signature_padding);
+
+ /**
+ * @brief gets an Interest or Data signature padding between maximum size and
+ * real size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] signature_size - retrieve the padding between maximum size and
+ * real size
+ * @return hICN error code
+ */
+ int (*get_signature_padding) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos, size_t *signature_padding);
+
+ /**
+ * @brief Gets the signature timestamp
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] signature_timestamp - Retrieved signature timestamp
+ * @return hICN error code
+ */
+ int (*get_signature_timestamp) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos,
+ uint64_t *signature_timestamp);
+
+ /**
+ * @brief Sets the signature timestamp
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] signature_timestamp - Signature timestamp to set
+ * @return hICN error code
+ */
+ int (*set_signature_timestamp) (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, uint64_t signature_timestamp);
+
+ /**
+ * @brief Gets the signature validation algorithm
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] validation_algorithm - Retrieved validation_algorithm
+ * @return hICN error code
+ */
+ int (*get_validation_algorithm) (const hicn_packet_buffer_t *pkbuf,
+ const size_t pos,
+ uint8_t *validation_algorithm);
+
+ /**
+ * @brief Sets the signature validation algorithm
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] validation_algorithm - Validation algorithm enumeration
+ * @return hICN error code
+ */
+ int (*set_validation_algorithm) (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, uint8_t validation_algorithm);
+
+ /**
+ * @brief Gets the key id
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] key_id - Retrieved key id first byte address
+ * @return hICN error code
+ */
+ int (*get_key_id) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size);
+
+ /**
+ * @brief Sets the key id
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] key_id - Key id first byte address
+ * @return hICN error code
+ */
+ int (*set_key_id) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *key_id, size_t size);
+
+ /**
+ * @brief Get a pointer to the signature field in the packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] signature - Pointer to the memory region holding the
+ * signature
+ * @return hICN error code
+ */
+ int (*get_signature) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ uint8_t **signature);
+
+ /**
+ * @brief Returns whether the packet holds a signature.
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] flag - Boolean indicating whether the packet has a signature.
+ * @return hICN error code
+ */
+ int (*has_signature) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ bool *flag);
+
+ /**
+ * @brief Set payload type of the packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [in] payload_type - The payload type of this packet
+ * @return hICN error code
+ */
+ int (*set_payload_type) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t payload_type);
+
+ /**
+ * @brief Get payload type from the packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] payload_type - The payload type of this packet
+ * @return hICN error code
+ */
+ int (*get_payload_type) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_payload_type_t *payload_type);
+
+ /**
+ * @brief Check if data packet is last one.
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] pos - Current position in the sequence of headers while
+ * executing command
+ * @param [out] is_last - 1 if last data, 0 otherwise
+ * @return hICN error code
+ */
+ int (*is_last_data) (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ int *is_last);
+
+ /**
+ * @brief Mark data packet as last
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * executing command
+ * @return hICN error code
+ */
+ int (*set_last_data) (const hicn_packet_buffer_t *pkbuf, size_t pos);
+
+ /**
+ * @brief Returns the packet TTL
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * @param [out] hops - Pointer to the variable receiving the TTL value
+ * @return hICN error code
+ */
+ int (*get_ttl) (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 *hops);
+
+ /**
+ * @brief Returns the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * @param [out] hops - The TTL value to set
+ * @return hICN error code
+ */
+ int (*set_ttl) (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 hops);
+
+ /**
+ * @brief Returns the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * @param [out] port - Pointer to the variable that will receive the port
+ * number
+ * @return hICN error code
+ */
+ int (*get_src_port) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 *port);
+
+ /**
+ * @brief Sets the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * @param [out] port - The port number to set
+ * @return hICN error code
+ */
+ int (*set_src_port) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 port);
+
+ /**
+ * @brief Returns the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * @param [out] port - Pointer to the variable that will receive the port
+ * number
+ * @return hICN error code
+ */
+ int (*get_dst_port) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 *port);
+
+ /**
+ * @brief Sets the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in, out] pos - Current position in the sequence of headers while
+ * @param [out] port - The port number to set
+ * @return hICN error code
+ */
+ int (*set_dst_port) (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 port);
+} hicn_ops_t;
+
+#define DECLARE_HICN_OPS(protocol, len) \
+ const hicn_ops_t hicn_ops_##protocol = { \
+ ATTR_INIT (name, #protocol), \
+ ATTR_INIT (header_len, len), \
+ ATTR_INIT (init_packet_header, protocol##_init_packet_header), \
+ ATTR_INIT (get_interest_locator, protocol##_get_interest_locator), \
+ ATTR_INIT (set_interest_locator, protocol##_set_interest_locator), \
+ ATTR_INIT (get_interest_name, protocol##_get_interest_name), \
+ ATTR_INIT (set_interest_name, protocol##_set_interest_name), \
+ ATTR_INIT (get_interest_name_suffix, \
+ protocol##_get_interest_name_suffix), \
+ ATTR_INIT (set_interest_name_suffix, \
+ protocol##_set_interest_name_suffix), \
+ ATTR_INIT (get_type, protocol##_get_type), \
+ ATTR_INIT (set_type, protocol##_set_type), \
+ ATTR_INIT (reset_interest_for_hash, protocol##_reset_interest_for_hash), \
+ ATTR_INIT (get_data_locator, protocol##_get_data_locator), \
+ ATTR_INIT (set_data_locator, protocol##_set_data_locator), \
+ ATTR_INIT (get_data_name, protocol##_get_data_name), \
+ ATTR_INIT (set_data_name, protocol##_set_data_name), \
+ ATTR_INIT (get_data_name_suffix, protocol##_get_data_name_suffix), \
+ ATTR_INIT (set_data_name_suffix, protocol##_set_data_name_suffix), \
+ ATTR_INIT (get_data_path_label, protocol##_get_data_path_label), \
+ ATTR_INIT (set_data_path_label, protocol##_set_data_path_label), \
+ ATTR_INIT (update_data_path_label, protocol##_update_data_path_label), \
+ ATTR_INIT (reset_data_for_hash, protocol##_reset_data_for_hash), \
+ ATTR_INIT (get_lifetime, protocol##_get_lifetime), \
+ ATTR_INIT (set_lifetime, protocol##_set_lifetime), \
+ ATTR_INIT (update_checksums, protocol##_update_checksums), \
+ ATTR_INIT (update_checksums_incremental, \
+ protocol##_update_checksums_incremental), \
+ ATTR_INIT (verify_checksums, protocol##_verify_checksums), \
+ ATTR_INIT (rewrite_interest, protocol##_rewrite_interest), \
+ ATTR_INIT (rewrite_data, protocol##_rewrite_data), \
+ ATTR_INIT (set_payload_len, protocol##_set_payload_len), \
+ ATTR_INIT (get_payload_type, protocol##_get_payload_type), \
+ ATTR_INIT (set_payload_type, protocol##_set_payload_type), \
+ ATTR_INIT (get_signature_size, protocol##_get_signature_size), \
+ ATTR_INIT (get_signature_timestamp, protocol##_get_signature_timestamp), \
+ ATTR_INIT (set_signature_timestamp, protocol##_set_signature_timestamp), \
+ ATTR_INIT (get_validation_algorithm, \
+ protocol##_get_validation_algorithm), \
+ ATTR_INIT (set_validation_algorithm, \
+ protocol##_set_validation_algorithm), \
+ ATTR_INIT (get_key_id, protocol##_get_key_id), \
+ ATTR_INIT (set_key_id, protocol##_set_key_id), \
+ ATTR_INIT (get_signature, protocol##_get_signature), \
+ ATTR_INIT (has_signature, protocol##_has_signature), \
+ ATTR_INIT (set_signature_padding, protocol##_set_signature_padding), \
+ ATTR_INIT (set_signature_size, protocol##_set_signature_size), \
+ ATTR_INIT (get_signature_padding, protocol##_get_signature_padding), \
+ ATTR_INIT (is_last_data, protocol##_is_last_data), \
+ ATTR_INIT (get_ttl, protocol##_get_ttl), \
+ ATTR_INIT (set_ttl, protocol##_set_ttl), \
+ ATTR_INIT (get_src_port, protocol##_get_src_port), \
+ ATTR_INIT (set_src_port, protocol##_set_src_port), \
+ ATTR_INIT (get_dst_port, protocol##_get_dst_port), \
+ ATTR_INIT (set_dst_port, protocol##_set_dst_port), \
+ }
+
+/**
+ * @brief Protocol-independent packet operations VFT
+ * NOTE: The following declarations should be kept in order
+ */
+extern const hicn_ops_t *const hicn_ops_vft[];
+
+#define PROT(pkbuf, pos) \
+ ((pos < (HICN_FORMAT_LEN - 1)) ? \
+ hicn_packet_get_format (pkbuf).as_u8[(pos) + 1] : \
+ IPPROTO_NONE)
+
+#define CALL_CHILD(method, pkbuf, pos, ...) \
+ hicn_ops_vft[PROT (pkbuf, (pos))]->method (pkbuf, (pos) + 1, ##__VA_ARGS__);
+
+#define CALL(method, pkbuf, ...) CALL_CHILD (method, pkbuf, -1, ##__VA_ARGS__)
+
+/** Shortcuts to entry points in VFT */
+#define HICN_OPS4 hicn_ops_vft[IPPROTO_IP]
+#define HICN_OPS6 hicn_ops_vft[IPPROTO_IPV6]
+
+/* Helpers for simple declarations */
+
+#define DECLARE_init_packet_header(protocol, error) \
+ int protocol##_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_interest_locator(protocol, error) \
+ int protocol##_get_interest_locator (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ hicn_ip_address_t *ip_address) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_interest_locator(protocol, error) \
+ int protocol##_set_interest_locator (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ const hicn_ip_address_t *ip_address) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_interest_name(protocol, error) \
+ int protocol##_get_interest_name (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, hicn_name_t *name) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_interest_name(protocol, error) \
+ int protocol##_set_interest_name (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, const hicn_name_t *name) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_interest_name_suffix(protocol, error) \
+ int protocol##_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ hicn_name_suffix_t *suffix) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_interest_name_suffix(protocol, error) \
+ int protocol##_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ const hicn_name_suffix_t *suffix) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_type(protocol, error) \
+ int protocol##_get_type (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, hicn_packet_type_t *type) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_type(protocol, error) \
+ int protocol##_set_type (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, hicn_packet_type_t type) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_reset_interest_for_hash(protocol, error) \
+ int protocol##_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, \
+ size_t pos) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_data_locator(protocol, error) \
+ int protocol##_get_data_locator (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ hicn_ip_address_t *ip_address) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_data_locator(protocol, error) \
+ int protocol##_set_data_locator (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ const hicn_ip_address_t *ip_address) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_data_name(protocol, error) \
+ int protocol##_get_data_name (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, hicn_name_t *name) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_data_name(protocol, error) \
+ int protocol##_set_data_name (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, const hicn_name_t *name) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_data_name_suffix(protocol, error) \
+ int protocol##_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ hicn_name_suffix_t *suffix) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_data_name_suffix(protocol, error) \
+ int protocol##_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ const hicn_name_suffix_t *suffix) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_data_path_label(protocol, error) \
+ int protocol##_get_data_path_label (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ hicn_path_label_t *path_label) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_data_path_label(protocol, error) \
+ int protocol##_set_data_path_label (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ const hicn_path_label_t path_label) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_update_data_path_label(protocol, error) \
+ int protocol##_update_data_path_label (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ const hicn_faceid_t face_id) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_reset_data_for_hash(protocol, error) \
+ int protocol##_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, \
+ size_t pos) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_lifetime(protocol, error) \
+ int protocol##_get_lifetime (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, hicn_lifetime_t *lifetime) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_lifetime(protocol, error) \
+ int protocol##_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ const hicn_lifetime_t lifetime) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_update_checksums(protocol, error) \
+ int protocol##_update_checksums (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, u16 partial_csum, \
+ size_t payload_len) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_update_checksums_incremental(protocol, error) \
+ int protocol##_update_checksums_incremental ( \
+ const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *old_val, \
+ u16 *new_val, u8 size, bool skip_first) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_verify_checksums(protocol, error) \
+ int protocol##_verify_checksums (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, u16 partial_csum, \
+ size_t payload_len) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_rewrite_interest(protocol, error) \
+ int protocol##_rewrite_interest ( \
+ const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ const hicn_ip_address_t *addr_new, hicn_ip_address_t *addr_old) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_rewrite_data(protocol, error) \
+ int protocol##_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ const hicn_ip_address_t *addr_new, \
+ hicn_ip_address_t *addr_old, \
+ const hicn_faceid_t face_id, u8 reset_pl) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_payload_len(protocol, error) \
+ int protocol##_set_payload_len (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, size_t payload_len) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_payload_type(protocol, error) \
+ int protocol##_get_payload_type (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ hicn_payload_type_t *payload_type) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_payload_type(protocol, error) \
+ int protocol##_set_payload_type (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ hicn_payload_type_t payload_type) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_signature_size(protocol, error) \
+ int protocol##_get_signature_size (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ size_t *signature_size) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_signature_size(protocol, error) \
+ int protocol##_set_signature_size (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, size_t signature_size) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_signature_padding(protocol, error) \
+ int protocol##_set_signature_padding (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, size_t padding) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_signature_padding(protocol, error) \
+ int protocol##_get_signature_padding (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, size_t *padding) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_signature_timestamp(protocol, error) \
+ int protocol##_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ uint64_t signature_timestamp) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_signature_timestamp(protocol, error) \
+ int protocol##_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ uint64_t *signature_timestamp) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_validation_algorithm(protocol, error) \
+ int protocol##_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos, \
+ uint8_t validation_algorithm) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_validation_algorithm(protocol, error) \
+ int protocol##_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, \
+ uint8_t *validation_algorithm) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_key_id(protocol, error) \
+ int protocol##_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ uint8_t *key_id, size_t size) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_key_id(protocol, error) \
+ int protocol##_get_key_id (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, uint8_t **key_id, \
+ uint8_t *key_id_size) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_signature(protocol, error) \
+ int protocol##_get_signature (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, uint8_t **signature) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_has_signature(protocol, error) \
+ int protocol##_has_signature (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, bool *flag) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_is_last_data(protocol, error) \
+ int protocol##_is_last_data (const hicn_packet_buffer_t *pkbuf, \
+ const size_t pos, int *is_last) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_last_data(protocol, error) \
+ int protocol##_set_last_data (const hicn_packet_buffer_t *pkbuf, \
+ size_t pos) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_ttl(protocol, error) \
+ int protocol##_get_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ u8 *hops) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_ttl(protocol, error) \
+ int protocol##_set_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ u8 hops) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_src_port(protocol, error) \
+ int protocol##_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ u16 *port) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_src_port(protocol, error) \
+ int protocol##_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ u16 port) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_get_dst_port(protocol, error) \
+ int protocol##_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ u16 *port) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#define DECLARE_set_dst_port(protocol, error) \
+ int protocol##_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \
+ u16 port) \
+ { \
+ return HICN_LIB_ERROR_##error; \
+ }
+
+#endif /* HICN_OPS_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/packet.c b/lib/src/packet.c
new file mode 100644
index 000000000..ccef568cd
--- /dev/null
+++ b/lib/src/packet.c
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2017-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.
+ */
+
+/**
+ * @file packet.c
+ * @brief Implementation of the compatibility layer.
+ */
+#ifndef _WIN32
+#include <netinet/in.h>
+#endif
+#include <string.h> // memset
+#include <stddef.h> // offsetof
+
+#include <hicn/common.h>
+#include <hicn/packet.h>
+#include <hicn/error.h>
+#include <hicn/name.h>
+#include <hicn/util/log.h>
+#include "ops.h"
+
+#define member_size(type, member) sizeof (((type *) 0)->member)
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
+
+#define HICN_NAME_COMPONENT_SIZE 2
+
+hicn_packet_format_t
+hicn_packet_get_format (const hicn_packet_buffer_t *pkbuf)
+{
+ return pkbuf->format;
+}
+
+void
+hicn_packet_set_format (hicn_packet_buffer_t *pkbuf,
+ hicn_packet_format_t format)
+{
+ pkbuf->format = format;
+}
+
+hicn_packet_type_t
+hicn_packet_get_type (const hicn_packet_buffer_t *pkbuf)
+{
+ return pkbuf->type;
+}
+
+void
+hicn_packet_set_type (hicn_packet_buffer_t *pkbuf, hicn_packet_type_t type)
+{
+ pkbuf->type = type;
+}
+
+bool
+hicn_packet_is_interest (const hicn_packet_buffer_t *pkbuf)
+{
+ return pkbuf->type == HICN_PACKET_TYPE_INTEREST;
+}
+
+bool
+hicn_packet_is_data (const hicn_packet_buffer_t *pkbuf)
+{
+ return pkbuf->type == HICN_PACKET_TYPE_DATA;
+}
+
+bool
+hicn_packet_is_undefined (const hicn_packet_buffer_t *pkbuf)
+{
+ return pkbuf->type == HICN_PACKET_TYPE_UNDEFINED;
+}
+
+int
+hicn_packet_init_header (hicn_packet_buffer_t *pkbuf,
+ size_t additional_header_size)
+{
+ if (hicn_packet_is_undefined (pkbuf))
+ return HICN_LIB_ERROR_UNEXPECTED;
+ if (hicn_packet_get_format (pkbuf).as_u32 == HICN_PACKET_FORMAT_NONE.as_u32)
+ return HICN_LIB_ERROR_UNEXPECTED;
+ if (!pkbuf_get_header (pkbuf))
+ return HICN_LIB_ERROR_UNEXPECTED;
+ pkbuf->len = 0;
+ pkbuf->payload = 0;
+
+ int rc = CALL (init_packet_header, pkbuf);
+
+ /*
+ * Additional header size is there for the signature, and assumes the AH
+ * header is always located at the end...
+ */
+ pkbuf->len += additional_header_size;
+ pkbuf->payload += additional_header_size;
+
+ return rc;
+}
+
+int
+hicn_packet_reset (hicn_packet_buffer_t *pkbuf)
+{
+ memset (pkbuf, 0, sizeof (hicn_packet_buffer_t));
+ hicn_packet_set_format (pkbuf, HICN_PACKET_FORMAT_NONE);
+ hicn_packet_set_type (pkbuf, HICN_PACKET_TYPE_UNDEFINED);
+ hicn_packet_set_len (pkbuf, 0);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_packet_analyze (hicn_packet_buffer_t *pkbuf)
+{
+ u8 *header = pkbuf_get_header (pkbuf);
+ u8 protocol;
+ u16 offset = 0;
+ bool has_signature;
+ size_t signature_size;
+ int rc;
+
+ hicn_packet_format_t *format = &pkbuf->format;
+
+ /* Bootstrap: assume IP packet, and get version from header */
+ switch (HICN_IP_VERSION (pkbuf_get_header (pkbuf)))
+ {
+ case 4:
+ protocol = IPPROTO_IP;
+ break;
+ case 6:
+ protocol = IPPROTO_IPV6;
+ break;
+ default:
+ goto ERR;
+ }
+
+ format->as_u32 = 0;
+ for (unsigned i = 0; i < HICN_FORMAT_LEN; i++)
+ {
+ format->as_u8[i] = protocol;
+
+ /* Next protocol + increment offset */
+ switch (protocol)
+ {
+
+ /*
+ * All packets either start with IPv4 or IPv6, so we take the
+ * opportunity to update packet length there
+ */
+ case IPPROTO_IP:
+ {
+ if (i > 0)
+ goto ERR;
+#ifdef OPAQUE_IP
+ pkbuf->ipv4 = offset;
+#else
+ assert (offset == 0);
+#endif /* OPAQUE_IP */
+ _ipv4_header_t *ipv4 = (_ipv4_header_t *) (header + offset);
+ protocol = ipv4->protocol;
+ offset += IPV4_HDRLEN;
+
+ // hicn_packet_set_len (pkbuf, htons (ipv4->len));
+ if (hicn_packet_get_len (pkbuf) != htons (ipv4->len))
+ {
+ ERROR ("Invalid packet size in IPv4 header %d != %d",
+ htons (ipv4->len), hicn_packet_get_len (pkbuf));
+ goto ERR;
+ }
+ break;
+ }
+ case IPPROTO_IPV6:
+ {
+ if (i > 0)
+ goto ERR;
+#ifdef OPAQUE_IP
+ pkbuf->ipv6 = offset;
+#else
+ assert (offset == 0);
+#endif /* OPAQUE_IP */
+ _ipv6_header_t *ipv6 = (_ipv6_header_t *) (header + offset);
+ protocol = ipv6->nxt;
+ offset += IPV6_HDRLEN;
+ // hicn_packet_set_len (pkbuf, IPV6_HDRLEN + htons (ipv6->len));
+ if (hicn_packet_get_len (pkbuf) != IPV6_HDRLEN + htons (ipv6->len))
+ {
+ ERROR ("Invalid packet size in IPv6 header %d != %d",
+ IPV6_HDRLEN + htons (ipv6->len),
+ hicn_packet_get_len (pkbuf));
+ goto ERR;
+ }
+ break;
+ }
+ case IPPROTO_TCP:
+ pkbuf->tcp = offset;
+ /* After TCP, we might eventually have a AH header */
+ rc = CALL_CHILD (has_signature, pkbuf, i - 1, &has_signature);
+ if (rc < 0)
+ goto ERR;
+ protocol = has_signature ? IPPROTO_AH : IPPROTO_NONE;
+ offset += TCP_HDRLEN;
+ break;
+ case IPPROTO_UDP:
+ pkbuf->udp = offset;
+ protocol = IPPROTO_ENCAP;
+ offset += UDP_HDRLEN;
+ break;
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
+ pkbuf->icmp = offset;
+ /* After ICMP, we might eventually have a AH header */
+ // CALL_CHILD (has_signature, pkbuf, i - 1, &has_signature);
+ protocol = /* has_signature ? IPPROTO_AH : */ IPPROTO_NONE;
+ offset += ICMP_HDRLEN;
+ break;
+
+ case IPPROTO_ENCAP:
+ pkbuf->newhdr = offset;
+ /* After ENCAP, we might eventually have a AH header */
+ rc = CALL_CHILD (has_signature, pkbuf, i - 1, &has_signature);
+ if (rc < 0)
+ goto ERR;
+ protocol = has_signature ? IPPROTO_AH : IPPROTO_NONE;
+ offset += NEW_HDRLEN;
+ break;
+
+ case IPPROTO_AH:
+ pkbuf->ah = offset;
+ protocol = IPPROTO_NONE;
+ offset += AH_HDRLEN;
+
+ rc = CALL_CHILD (get_signature_size, pkbuf, i - 1, &signature_size);
+ if (rc < 0)
+ goto ERR;
+ offset += signature_size;
+ break;
+
+ case IPPROTO_NONE:
+ /* NONE until we terminate the list of protocols */
+ break;
+
+ default:
+ goto ERR;
+ }
+ }
+ pkbuf->payload = offset;
+
+ rc = CALL (get_type, pkbuf, &pkbuf->type);
+ if (rc < 0)
+ goto ERR;
+
+ return HICN_LIB_ERROR_NONE;
+
+ERR:
+ *format = HICN_PACKET_FORMAT_NONE;
+ pkbuf->type = HICN_PACKET_TYPE_UNDEFINED;
+ return HICN_LIB_ERROR_UNEXPECTED;
+}
+
+int
+hicn_packet_set_buffer (hicn_packet_buffer_t *pkbuf, u8 *buffer,
+ uint16_t buffer_size, uint16_t len)
+{
+ pkbuf_set_header (pkbuf, buffer);
+ pkbuf->buffer_size = buffer_size;
+ pkbuf->len = len;
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_packet_get_buffer (const hicn_packet_buffer_t *pkbuf, u8 **buffer,
+ uint16_t *buffer_size, uint16_t *len)
+{
+ *buffer = pkbuf_get_header (pkbuf);
+ *buffer_size = pkbuf->buffer_size;
+ *len = pkbuf->len;
+ return HICN_LIB_ERROR_NONE;
+}
+
+size_t
+hicn_packet_get_len (const hicn_packet_buffer_t *pkbuf)
+{
+ return pkbuf->len;
+}
+
+int
+hicn_packet_set_len (hicn_packet_buffer_t *pkbuf, size_t len)
+{
+ pkbuf->len = len;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_packet_get_header_len (const hicn_packet_buffer_t *pkbuf, size_t *len)
+{
+ *len = pkbuf->payload;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_packet_get_payload_len (const hicn_packet_buffer_t *pkbuf, size_t *len)
+{
+ *len = hicn_packet_get_len (pkbuf) - pkbuf->payload;
+ return HICN_LIB_ERROR_NONE;
+}
+
+// XXX this fails with chained membufs in libtransport
+int
+hicn_packet_set_payload (const hicn_packet_buffer_t *pkbuf, const u8 *payload,
+ u16 payload_len)
+{
+ memcpy (pkbuf_get_header (pkbuf) + pkbuf->payload, payload, payload_len);
+
+ return CALL (set_payload_len, pkbuf, payload_len);
+}
+
+int
+hicn_packet_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
+ size_t *payload_size, bool hard_copy)
+{
+ size_t payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload;
+
+ if (hard_copy)
+ {
+ memcpy (payload, pkbuf_get_header (pkbuf) + pkbuf->payload, payload_len);
+ }
+ else
+ {
+ *payload = pkbuf_get_header (pkbuf) + pkbuf->payload;
+ }
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+/* Header fields manipulation */
+
+int
+hicn_packet_get_header_length_from_format (hicn_packet_format_t format,
+ size_t *header_length)
+{
+ *header_length = 0;
+ for (unsigned i = 0; i < HICN_FORMAT_LEN; i++)
+ {
+ *header_length += hicn_ops_vft[format.as_u8[i]]->header_len;
+ }
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_packet_compute_checksum (const hicn_packet_buffer_t *pkbuf)
+{
+ return CALL (update_checksums, pkbuf, 0, ~0);
+}
+
+int
+hicn_packet_compute_header_checksum (const hicn_packet_buffer_t *pkbuf,
+ u16 init_sum)
+{
+ /* payload_len == 0: ignore payload */
+ return CALL (update_checksums, pkbuf, init_sum, 0);
+}
+
+int
+hicn_packet_check_integrity_no_payload (const hicn_packet_buffer_t *pkbuf,
+ u16 init_sum)
+{
+ return CALL (verify_checksums, pkbuf, init_sum, 0);
+}
+
+int
+hicn_packet_set_payload_length (const hicn_packet_buffer_t *pkbuf,
+ const size_t payload_len)
+{
+ return CALL (set_payload_len, pkbuf, payload_len);
+}
+
+int
+hicn_packet_compare (const hicn_packet_buffer_t *pkbuf1,
+ const hicn_packet_buffer_t *pkbuf2)
+{
+
+ hicn_packet_format_t format1 = hicn_packet_get_format (pkbuf1);
+ hicn_packet_format_t format2 = hicn_packet_get_format (pkbuf2);
+
+ if (format1.as_u32 != format2.as_u32)
+ return HICN_LIB_ERROR_UNEXPECTED;
+
+ size_t len1 = hicn_packet_get_len (pkbuf1);
+ size_t len2 = hicn_packet_get_len (pkbuf2);
+
+ if (len1 != len2)
+ return HICN_LIB_ERROR_UNEXPECTED;
+
+ return memcmp (pkbuf_get_header (pkbuf1), pkbuf_get_header (pkbuf2), len1);
+}
+
+int
+hicn_packet_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name)
+{
+ switch (pkbuf->type)
+ {
+ case HICN_PACKET_TYPE_INTEREST:
+ return hicn_interest_get_name (pkbuf, name);
+ case HICN_PACKET_TYPE_DATA:
+ return hicn_data_get_name (pkbuf, name);
+ default:
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+}
+
+int
+hicn_packet_set_name (const hicn_packet_buffer_t *pkbuf,
+ const hicn_name_t *name)
+{
+ switch (pkbuf->type)
+ {
+ case HICN_PACKET_TYPE_INTEREST:
+ return hicn_interest_set_name (pkbuf, name);
+ case HICN_PACKET_TYPE_DATA:
+ return hicn_data_set_name (pkbuf, name);
+ default:
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+}
+
+int
+hicn_packet_get_locator (const hicn_packet_buffer_t *pkbuf,
+ hicn_ip_address_t *address)
+{
+ switch (pkbuf->type)
+ {
+ case HICN_PACKET_TYPE_INTEREST:
+ return hicn_interest_get_locator (pkbuf, address);
+ case HICN_PACKET_TYPE_DATA:
+ return hicn_data_get_locator (pkbuf, address);
+ default:
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+}
+
+int
+hicn_packet_set_locator (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *address)
+{
+ switch (pkbuf->type)
+ {
+ case HICN_PACKET_TYPE_INTEREST:
+ return hicn_interest_set_locator (pkbuf, address);
+ case HICN_PACKET_TYPE_DATA:
+ return hicn_data_set_locator (pkbuf, address);
+ default:
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+}
+
+int
+hicn_packet_get_signature_size (const hicn_packet_buffer_t *pkbuf,
+ size_t *bytes)
+{
+ return CALL (get_signature_size, pkbuf, bytes);
+}
+
+int
+hicn_packet_set_signature_size (const hicn_packet_buffer_t *pkbuf,
+ size_t bytes)
+{
+ return CALL (set_signature_size, pkbuf, bytes);
+}
+
+int
+hicn_packet_get_signature_padding (const hicn_packet_buffer_t *pkbuf,
+ size_t *bytes)
+{
+ return CALL (get_signature_padding, pkbuf, bytes);
+}
+
+int
+hicn_packet_set_signature_padding (const hicn_packet_buffer_t *pkbuf,
+ size_t bytes)
+{
+ return CALL (set_signature_padding, pkbuf, bytes);
+}
+
+int
+hicn_packet_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf,
+ uint64_t signature_timestamp)
+{
+ return CALL (set_signature_timestamp, pkbuf, signature_timestamp);
+}
+
+int
+hicn_packet_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf,
+ uint64_t *signature_timestamp)
+{
+ return CALL (get_signature_timestamp, pkbuf, signature_timestamp);
+}
+
+int
+hicn_packet_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf,
+ uint8_t validation_algorithm)
+{
+ return CALL (set_validation_algorithm, pkbuf, validation_algorithm);
+}
+
+int
+hicn_packet_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf,
+ uint8_t *validation_algorithm)
+{
+ return CALL (get_validation_algorithm, pkbuf, validation_algorithm);
+}
+
+int
+hicn_packet_set_key_id (const hicn_packet_buffer_t *pkbuf, uint8_t *key_id,
+ size_t key_len)
+{
+ return CALL (set_key_id, pkbuf, key_id, key_len);
+}
+
+int
+hicn_packet_get_key_id (const hicn_packet_buffer_t *pkbuf, uint8_t **key_id,
+ uint8_t *key_id_len)
+{
+ return CALL (get_key_id, pkbuf, key_id, key_id_len);
+}
+
+int
+hicn_packet_get_lifetime (const hicn_packet_buffer_t *pkbuf,
+ hicn_lifetime_t *lifetime)
+{
+ return CALL (get_lifetime, pkbuf, lifetime);
+}
+
+int
+hicn_packet_set_lifetime (const hicn_packet_buffer_t *pkbuf,
+ hicn_lifetime_t lifetime)
+{
+ return CALL (set_lifetime, pkbuf, lifetime);
+}
+
+int
+hicn_packet_get_payload_type (const hicn_packet_buffer_t *pkbuf,
+ hicn_payload_type_t *payload_type)
+{
+ return CALL (get_payload_type, pkbuf, payload_type);
+}
+
+int
+hicn_packet_set_payload_type (const hicn_packet_buffer_t *pkbuf,
+ hicn_payload_type_t payload_type)
+{
+ return CALL (set_payload_type, pkbuf, payload_type);
+}
+
+int
+hicn_packet_save_header (const hicn_packet_buffer_t *pkbuf, u8 *header,
+ size_t *header_len, bool copy_ah)
+{
+ hicn_packet_format_t format = hicn_packet_get_format (pkbuf);
+ if (copy_ah || !_is_ah (format))
+ {
+ int rc = hicn_packet_get_header_len (pkbuf, header_len);
+ if (HICN_LIB_IS_ERROR (rc))
+ return rc;
+ }
+ else
+ {
+ /* Copy up until the ah header (which we assume is last) */
+ *header_len = pkbuf->ah;
+ }
+
+ memcpy (header, pkbuf_get_header (pkbuf), *header_len);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_packet_load_header (const hicn_packet_buffer_t *pkbuf, const u8 *header,
+ size_t header_len)
+{
+ memcpy (pkbuf_get_header (pkbuf), header, header_len);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+/* Interest */
+
+int
+hicn_interest_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name)
+{
+ return CALL (get_interest_name, pkbuf, name);
+}
+
+int
+hicn_interest_set_name (const hicn_packet_buffer_t *pkbuf,
+ const hicn_name_t *name)
+{
+ return CALL (set_interest_name, pkbuf, name);
+}
+
+int
+hicn_interest_get_locator (const hicn_packet_buffer_t *pkbuf,
+ hicn_ip_address_t *address)
+{
+ return CALL (get_interest_locator, pkbuf, address);
+}
+
+int
+hicn_interest_set_locator (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *address)
+{
+ return CALL (set_interest_locator, pkbuf, address);
+}
+
+int
+hicn_interest_compare (const hicn_packet_buffer_t *pkbuf1,
+ const hicn_packet_buffer_t *pkbuf2)
+{
+ return hicn_packet_compare (pkbuf1, pkbuf2);
+}
+
+int
+hicn_interest_get_lifetime (const hicn_packet_buffer_t *pkbuf,
+ hicn_lifetime_t *lifetime)
+{
+ return hicn_packet_get_lifetime (pkbuf, lifetime);
+}
+
+int
+hicn_interest_set_lifetime (const hicn_packet_buffer_t *pkbuf,
+ hicn_lifetime_t lifetime)
+{
+ return hicn_packet_set_lifetime (pkbuf, lifetime);
+}
+
+int
+hicn_interest_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
+ size_t *payload_size, bool hard_copy)
+{
+ return hicn_packet_get_payload (pkbuf, payload, payload_size, hard_copy);
+}
+
+int
+hicn_interest_set_payload (const hicn_packet_buffer_t *pkbuf,
+ const u8 *payload, size_t payload_len)
+{
+ return hicn_packet_set_payload (pkbuf, payload, (u16) payload_len);
+}
+
+int
+hicn_interest_reset_for_hash (hicn_packet_buffer_t *pkbuf)
+{
+ return CALL (reset_interest_for_hash, pkbuf);
+}
+
+/* Data */
+
+int
+hicn_data_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name)
+{
+ return CALL (get_data_name, pkbuf, name);
+}
+
+int
+hicn_data_set_name (const hicn_packet_buffer_t *pkbuf, const hicn_name_t *name)
+{
+ return CALL (set_data_name, pkbuf, name);
+}
+
+int
+hicn_data_get_locator (const hicn_packet_buffer_t *pkbuf,
+ hicn_ip_address_t *address)
+{
+ return CALL (get_data_locator, pkbuf, address);
+}
+
+int
+hicn_data_set_locator (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *address)
+{
+ return CALL (set_data_locator, pkbuf, address);
+}
+
+int
+hicn_data_compare (const hicn_packet_buffer_t *pkbuf1,
+ const hicn_packet_buffer_t *pkbuf2)
+{
+ return hicn_packet_compare (pkbuf1, pkbuf2);
+}
+
+int
+hicn_data_get_expiry_time (const hicn_packet_buffer_t *pkbuf,
+ hicn_lifetime_t *expiry_time)
+{
+ return hicn_packet_get_lifetime (pkbuf, expiry_time);
+}
+
+int
+hicn_data_set_expiry_time (const hicn_packet_buffer_t *pkbuf,
+ hicn_lifetime_t expiry_time)
+{
+ return hicn_packet_set_lifetime (pkbuf, expiry_time);
+}
+
+/* Path label */
+
+int
+hicn_data_get_path_label (const hicn_packet_buffer_t *pkbuf,
+ hicn_path_label_t *path_label)
+{
+ return CALL (get_data_path_label, pkbuf, path_label);
+}
+
+int
+hicn_get_path_label (const hicn_packet_buffer_t *pkbuf,
+ hicn_path_label_t *path_label)
+{
+ if (!hicn_packet_is_data (pkbuf))
+ return INVALID_PATH_LABEL;
+ return hicn_data_get_path_label (pkbuf, path_label);
+}
+
+int
+hicn_data_set_path_label (const hicn_packet_buffer_t *pkbuf,
+ hicn_path_label_t path_label)
+{
+ return CALL (set_data_path_label, pkbuf, path_label);
+}
+
+int
+hicn_data_set_payload (const hicn_packet_buffer_t *pkbuf, const u8 *payload,
+ size_t payload_len)
+{
+ return hicn_packet_set_payload (pkbuf, payload, (u16) payload_len);
+}
+
+int
+hicn_data_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
+ size_t *payload_size, bool hard_copy)
+{
+ return hicn_packet_get_payload (pkbuf, payload, payload_size, hard_copy);
+}
+
+int
+hicn_data_reset_for_hash (hicn_packet_buffer_t *pkbuf)
+{
+ return CALL (reset_data_for_hash, pkbuf);
+}
+
+int
+hicn_data_is_last (const hicn_packet_buffer_t *pkbuf, int *is_last)
+{
+ return CALL (is_last_data, pkbuf, is_last);
+}
+
+int
+hicn_data_set_last (const hicn_packet_buffer_t *pkbuf)
+{
+ return CALL (set_last_data, pkbuf);
+}
+
+int
+hicn_packet_get_signature (const hicn_packet_buffer_t *pkbuf,
+ uint8_t **sign_buf)
+{
+ return CALL (get_signature, pkbuf, sign_buf);
+}
+
+int
+hicn_packet_get_ttl (const hicn_packet_buffer_t *pkbuf, u8 *hops)
+{
+ return CALL (get_ttl, pkbuf, hops);
+}
+
+int
+hicn_packet_set_ttl (const hicn_packet_buffer_t *pkbuf, u8 hops)
+{
+ return CALL (set_ttl, pkbuf, hops);
+}
+
+int
+hicn_packet_get_src_port (const hicn_packet_buffer_t *pkbuf, u16 *port)
+{
+ return CALL (get_src_port, pkbuf, port);
+}
+
+int
+hicn_packet_set_src_port (const hicn_packet_buffer_t *pkbuf, u16 port)
+{
+ return CALL (set_src_port, pkbuf, port);
+}
+
+int
+hicn_packet_get_dst_port (const hicn_packet_buffer_t *pkbuf, u16 *port)
+{
+ return CALL (get_dst_port, pkbuf, port);
+}
+
+int
+hicn_packet_set_dst_port (const hicn_packet_buffer_t *pkbuf, u16 port)
+{
+ return CALL (set_dst_port, pkbuf, port);
+}
+
+int
+hicn_interest_rewrite (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
+{
+ return CALL (rewrite_interest, pkbuf, addr_new, addr_old);
+}
+
+int
+hicn_data_rewrite (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
+{
+ return CALL (rewrite_data, pkbuf, addr_new, addr_old, face_id, reset_pl);
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol.h b/lib/src/protocol.h
new file mode 100644
index 000000000..58bbb2ac2
--- /dev/null
+++ b/lib/src/protocol.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file protocol.h
+ * @brief Protocol header definitions
+ */
+#ifndef HICN_PROTOCOL_H
+#define HICN_PROTOCOL_H
+
+#include "protocol/ah.h"
+#include "protocol/ipv4.h"
+#include "protocol/ipv6.h"
+#include "protocol/icmp.h"
+#include "protocol/icmprd.h"
+#include "protocol/tcp.h"
+#include "protocol/udp.h"
+#include "protocol/new.h"
+
+#endif /* HICN_PROTOCOL_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/ah.c b/lib/src/protocol/ah.c
index c9ed40179..9cc747ac8 100644
--- a/lib/src/protocol/ah.c
+++ b/lib/src/protocol/ah.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -18,12 +18,12 @@
* @brief hICN operations for AH header
*/
-#include <string.h> // memcpy
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/header.h>
-#include <hicn/ops.h>
-#include <hicn/protocol/ah.h>
+#include <string.h> // memcpy
+
+#include "../ops.h"
+#include "ah.h"
DECLARE_get_interest_locator (ah, UNEXPECTED);
DECLARE_set_interest_locator (ah, UNEXPECTED);
@@ -31,218 +31,248 @@ DECLARE_get_interest_name (ah, UNEXPECTED);
DECLARE_set_interest_name (ah, UNEXPECTED);
DECLARE_get_interest_name_suffix (ah, UNEXPECTED);
DECLARE_set_interest_name_suffix (ah, UNEXPECTED);
-DECLARE_is_interest (ah, UNEXPECTED);
-DECLARE_mark_packet_as_interest (ah, UNEXPECTED);
-DECLARE_mark_packet_as_data (ah, UNEXPECTED);
+DECLARE_get_type (ah, UNEXPECTED);
+DECLARE_set_type (ah, UNEXPECTED);
DECLARE_get_data_locator (ah, UNEXPECTED);
DECLARE_set_data_locator (ah, UNEXPECTED);
DECLARE_get_data_name (ah, UNEXPECTED);
DECLARE_set_data_name (ah, UNEXPECTED);
DECLARE_get_data_name_suffix (ah, UNEXPECTED);
DECLARE_set_data_name_suffix (ah, UNEXPECTED);
-DECLARE_get_data_pathlabel (ah, UNEXPECTED);
-DECLARE_set_data_pathlabel (ah, UNEXPECTED);
-DECLARE_update_data_pathlabel (ah, UNEXPECTED);
+DECLARE_get_data_path_label (ah, UNEXPECTED);
+DECLARE_set_data_path_label (ah, UNEXPECTED);
+DECLARE_update_data_path_label (ah, UNEXPECTED);
DECLARE_get_lifetime (ah, UNEXPECTED);
DECLARE_set_lifetime (ah, UNEXPECTED);
-DECLARE_get_source_port (ah, UNEXPECTED);
-DECLARE_get_dest_port (ah, UNEXPECTED);
-DECLARE_set_source_port (ah, UNEXPECTED);
-DECLARE_set_dest_port (ah, UNEXPECTED);
-DECLARE_get_payload_length (ah, UNEXPECTED);
-DECLARE_set_payload_length (ah, UNEXPECTED);
+// DECLARE_get_payload_len (ah, UNEXPECTED);
+DECLARE_set_payload_len (ah, UNEXPECTED);
DECLARE_get_payload_type (ah, UNEXPECTED);
DECLARE_set_payload_type (ah, UNEXPECTED);
DECLARE_is_last_data (ah, UNEXPECTED);
DECLARE_set_last_data (ah, UNEXPECTED);
+DECLARE_get_ttl (ah, UNEXPECTED);
+DECLARE_set_ttl (ah, UNEXPECTED);
+DECLARE_get_src_port (ah, UNEXPECTED);
+DECLARE_set_src_port (ah, UNEXPECTED);
+DECLARE_get_dst_port (ah, UNEXPECTED);
+DECLARE_set_dst_port (ah, UNEXPECTED);
int
-ah_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+ah_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- /* *INDENT-OFF* */
- h->ah = (_ah_header_t){
+ pkbuf->ah = pkbuf->len;
+ if (AH_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += AH_HDRLEN;
+
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ /* clang-format off */
+ *ah = (_ah_header_t){
.nh = (u8) 0,
.payloadlen = (u8) 0,
.reserved = (u16) 0,
};
- /* *INDENT-ON* */
- return CHILD_OPS (init_packet_header, type, h);
+ /* clang-format on */
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-ah_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
+ah_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
size_t signature_size;
- int rc =
- hicn_ops_vft[type.l1]->get_signature_size (type, h, &signature_size);
+ int rc = CALL (get_signature_size, pkbuf, &signature_size);
if (rc < 0)
return rc;
- memset (&(h->ah.validationPayload), 0, signature_size);
- h->ah.signaturePadding = 0;
- return CHILD_OPS (reset_interest_for_hash, type, h);
+ memset (&(ah->validationPayload), 0, signature_size);
+ ah->signaturePadding = 0;
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-ah_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+ah_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
size_t signature_size;
- int rc =
- hicn_ops_vft[type.l1]->get_signature_size (type, h, &signature_size);
+ int rc = CALL (get_signature_size, pkbuf, &signature_size);
if (rc < 0)
return rc;
- memset (&(h->ah.validationPayload), 0, signature_size);
- h->ah.signaturePadding = 0;
- return CHILD_OPS (reset_interest_for_hash, type, h);
+ memset (&(ah->validationPayload), 0, signature_size);
+ ah->signaturePadding = 0;
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-ah_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+ah_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
/* Nothing to do as there is no checksum in AH */
return HICN_LIB_ERROR_NONE;
}
int
-ah_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+ah_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 *old_val, u16 *new_val, u8 size,
+ bool skip_first)
{
- /* Nothing to do as there is no checksum in AH */
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val,
+ new_val, size, false);
}
int
-ah_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+ah_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- /* Nothing to do on signature */
+ /* Nothing to do as there is no checksum in AH */
return HICN_LIB_ERROR_NONE;
}
int
-ah_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+ah_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
/* Nothing to do on signature */
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_length (hicn_type_t type, const hicn_protocol_t *h, size_t *length)
-{
- return HICN_LIB_ERROR_NOT_IMPLEMENTED;
-}
-
-int
-ah_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ah_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
- *header_length = AH_HDRLEN + (h->ah.payloadlen << 2);
+ /* Nothing to do on signature */
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ah_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **signature)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *header_length = AH_HDRLEN + (h->ah.payloadlen << 2) + child_header_length;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ *signature = ah->validationPayload;
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature)
+ah_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag)
{
- *signature = h->ah.validationPayload;
+ *flag = true;
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
+ah_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *signature_size)
{
- *signature_size = h->ah.payloadlen << 2;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ *signature_size = ah->payloadlen << 2;
return HICN_LIB_ERROR_NONE;
}
int
-ah_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
- const size_t signature_size)
+ah_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t signature_size)
{
- h->ah.payloadlen = signature_size >> 2;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ ah->payloadlen = signature_size >> 2;
return HICN_LIB_ERROR_NONE;
}
int
-ah_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
+ah_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t signature_timestamp)
{
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
uint64_t netwok_order_timestamp = htonll (signature_timestamp);
- memcpy (h->ah.timestamp_as_u8, &netwok_order_timestamp, sizeof (uint64_t));
+ memcpy (ah->timestamp_as_u8, &netwok_order_timestamp, sizeof (uint64_t));
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
+ah_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t *signature_timestamp)
{
- memcpy (signature_timestamp, h->ah.timestamp_as_u8, sizeof (uint64_t));
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ memcpy (signature_timestamp, ah->timestamp_as_u8, sizeof (uint64_t));
*signature_timestamp = ntohll (*signature_timestamp);
return HICN_LIB_ERROR_NONE;
}
int
-ah_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
+ah_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t validation_algorithm)
{
- h->ah.validationAlgorithm = validation_algorithm;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ ah->validationAlgorithm = validation_algorithm;
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
+ah_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t *validation_algorithm)
{
- *validation_algorithm = h->ah.validationAlgorithm;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ *validation_algorithm = ah->validationAlgorithm;
return HICN_LIB_ERROR_NONE;
}
int
-ah_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, size_t padding)
+ah_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t padding)
{
- h->ah.signaturePadding = padding;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ ah->signaturePadding = padding;
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
+ah_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *padding)
{
- *padding = h->ah.signaturePadding;
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ *padding = ah->signaturePadding;
return HICN_LIB_ERROR_NONE;
}
int
-ah_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+ah_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id,
+ size_t size)
{
- memcpy (h->ah.keyId, key_id, sizeof (h->ah.keyId));
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ if (size != sizeof (ah->keyId))
+ return HICN_LIB_ERROR_INVALID_PARAMETER;
+
+ memcpy (ah->keyId, key_id, sizeof (ah->keyId));
return HICN_LIB_ERROR_NONE;
}
int
-ah_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
+ah_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t **key_id,
uint8_t *key_id_size)
{
- *key_id = h->ah.keyId;
- *key_id_size = sizeof (h->ah.keyId);
+ _ah_header_t *ah = pkbuf_get_ah (pkbuf);
+
+ *key_id = ah->keyId;
+ *key_id_size = sizeof (ah->keyId);
return HICN_LIB_ERROR_NONE;
}
-DECLARE_HICN_OPS (ah);
+DECLARE_HICN_OPS (ah, AH_HDRLEN);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/lib/src/protocol/ah.h b/lib/src/protocol/ah.h
new file mode 100644
index 000000000..ee124f92a
--- /dev/null
+++ b/lib/src/protocol/ah.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+/**
+ * @file protocol/ah.h
+ * @brief AH packet header
+ */
+#ifndef HICN_PROTOCOL_AH_H
+#define HICN_PROTOCOL_AH_H
+
+#include <hicn/common.h>
+
+/*
+ * The TCP PSH flag is set to indicate TCP payload in fact contains a AH header
+ * with signature information for the packet
+ */
+#define AH_FLAG 0x10
+
+/*
+ * The length of the AH struct must be 44 bytes.
+ */
+#define EXPECTED_AH_HDRLEN 44
+
+typedef struct
+{
+ u8 nh; // To match with reserved in IPSEC AH
+ // Length of the signature field. Note that the signature might be smaller
+ // than the field: the actual size is computed from the field size and
+ // signaturePadding.
+ u8 payloadlen;
+ union
+ {
+ u16 reserved;
+
+ struct
+ {
+ u8 validationAlgorithm;
+ u8 signaturePadding;
+ };
+ };
+ union
+ {
+ struct
+ {
+ u32 spi;
+ u32 seq;
+ };
+ // Unix timestamp indicating when the signature has been calculated
+ u8 timestamp_as_u8[8];
+ u16 timestamp_as_u16[4];
+ u32 timestamp_as_u32[2];
+ };
+ // ICV would follow
+ u8 keyId[32]; // Hash of pub key
+ /* 44 B + validationPayload */
+ u8 validationPayload[0]; // Holds the signature
+} _ah_header_t;
+
+#define AH_HDRLEN sizeof (_ah_header_t)
+static_assert (EXPECTED_AH_HDRLEN == AH_HDRLEN,
+ "Size of AH Struct does not match its expected size.");
+
+#endif /* HICN_PROTOCOL_AH_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/icmp.c b/lib/src/protocol/icmp.c
index 1fc6c7d2f..71417a4e0 100644
--- a/lib/src/protocol/icmp.c
+++ b/lib/src/protocol/icmp.c
@@ -13,10 +13,11 @@
* limitations under the License.
*/
-#include <string.h>
-#include <hicn/protocol/icmp.h>
#include <hicn/error.h>
-#include <hicn/ops.h>
+#include <string.h>
+
+#include "icmp.h"
+#include "../ops.h"
DECLARE_get_interest_locator (icmp, UNEXPECTED);
DECLARE_set_interest_locator (icmp, UNEXPECTED);
@@ -24,89 +25,110 @@ DECLARE_get_interest_name (icmp, UNEXPECTED);
DECLARE_set_interest_name (icmp, UNEXPECTED);
DECLARE_get_interest_name_suffix (icmp, UNEXPECTED);
DECLARE_set_interest_name_suffix (icmp, UNEXPECTED);
-DECLARE_is_interest (icmp, UNEXPECTED);
-DECLARE_mark_packet_as_interest (icmp, UNEXPECTED);
-DECLARE_mark_packet_as_data (icmp, UNEXPECTED);
DECLARE_get_data_locator (icmp, UNEXPECTED);
DECLARE_set_data_locator (icmp, UNEXPECTED);
DECLARE_get_data_name (icmp, UNEXPECTED);
DECLARE_set_data_name (icmp, UNEXPECTED);
DECLARE_get_data_name_suffix (icmp, UNEXPECTED);
DECLARE_set_data_name_suffix (icmp, UNEXPECTED);
-DECLARE_get_data_pathlabel (icmp, UNEXPECTED);
-DECLARE_set_data_pathlabel (icmp, UNEXPECTED);
-DECLARE_update_data_pathlabel (icmp, UNEXPECTED);
+DECLARE_get_data_path_label (icmp, UNEXPECTED);
+DECLARE_set_data_path_label (icmp, UNEXPECTED);
+DECLARE_update_data_path_label (icmp, UNEXPECTED);
DECLARE_get_lifetime (icmp, UNEXPECTED);
DECLARE_set_lifetime (icmp, UNEXPECTED);
-DECLARE_get_source_port (icmp, UNEXPECTED);
-DECLARE_get_dest_port (icmp, UNEXPECTED);
-DECLARE_set_source_port (icmp, UNEXPECTED);
-DECLARE_set_dest_port (icmp, UNEXPECTED);
-DECLARE_get_length (icmp, UNEXPECTED);
-DECLARE_get_payload_length (icmp, UNEXPECTED);
-DECLARE_set_payload_length (icmp, UNEXPECTED);
+// DECLARE_get_payload_len (icmp, UNEXPECTED);
+DECLARE_set_payload_len (icmp, UNEXPECTED);
DECLARE_get_payload_type (icmp, UNEXPECTED);
DECLARE_set_payload_type (icmp, UNEXPECTED);
DECLARE_get_signature (icmp, UNEXPECTED);
+DECLARE_has_signature (icmp, UNEXPECTED);
DECLARE_is_last_data (icmp, UNEXPECTED);
DECLARE_set_last_data (icmp, UNEXPECTED);
+DECLARE_get_ttl (icmp, UNEXPECTED);
+DECLARE_set_ttl (icmp, UNEXPECTED);
+DECLARE_get_src_port (icmp, UNEXPECTED);
+DECLARE_set_src_port (icmp, UNEXPECTED);
+DECLARE_get_dst_port (icmp, UNEXPECTED);
+DECLARE_set_dst_port (icmp, UNEXPECTED);
int
-icmp_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+icmp_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- h->icmp = (_icmp_header_t){
+ pkbuf->icmp = pkbuf->len;
+ if (ICMP_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += ICMP_HDRLEN;
+
+ _icmp_header_t *icmp = pkbuf_get_icmp (pkbuf);
+
+ *icmp = (_icmp_header_t){
.type = 0,
.code = 0,
.csum = 0,
};
- return HICN_LIB_ERROR_NONE; // CHILD_OPS(init_packet_header, type, h->icmp);
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-icmp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
+icmp_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- h->icmp.csum = 0;
+ _icmp_header_t *icmp = pkbuf_get_icmp (pkbuf);
+
+ icmp->csum = 0;
- return CHILD_OPS (reset_interest_for_hash, type, h);
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-icmp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+icmp_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- h->icmp.csum = 0;
+ _icmp_header_t *icmp = pkbuf_get_icmp (pkbuf);
+
+ icmp->csum = 0;
- return CHILD_OPS (reset_data_for_hash, type, h);
+ return CALL_CHILD (reset_data_for_hash, pkbuf, pos);
}
int
-icmp_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+icmp_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
- // h->icmp.csum = 0;
- // h->icmp.csum = csum(h->bytes, TCP_HDRLEN + payload_length,
+ // icmp->csum = 0;
+ // icmp->csum = csum(h->bytes, TCP_HDRLEN + payload_len,
// ~partial_csum);
//
- // return CHILD_OPS(update_checksums, type, h->icmp, 0, payload_length);
+ // return CALL_CHILD(update_checksums, pkbuf, pos->icmp, 0,
+ // payload_len);
}
int
-icmp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+icmp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first)
{
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
- // if (csum(h->bytes, TCP_HDRLEN + payload_length, ~partial_csum) != 0)
+}
+
+int
+icmp_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
+{
+ return HICN_LIB_ERROR_NOT_IMPLEMENTED;
+ // if (csum(h->bytes, TCP_HDRLEN + payload_len, ~partial_csum) != 0)
// return HICN_LIB_ERROR_CORRUPTED_PACKET;
- // return CHILD_OPS(verify_checksums, type, h->icmp, 0, payload_length);
+ // return CALL_CHILD(verify_checksums, pkbuf, pos->icmp, 0,
+ // payload_len);
}
int
-icmp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+icmp_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
- // u16 *icmp_checksum = &(h->icmp.csum);
+ // u16 *icmp_checksum = &(icmp->csum);
//
// /*
// * Padding fields are set to zero so we can apply checksum on the
@@ -127,12 +149,13 @@ icmp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
}
int
-icmp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+icmp_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
- // u16 *icmp_checksum = &(h->icmp.csum);
+ // u16 *icmp_checksum = &(icmp->csum);
//
// /*
// * Padding fields are set to zero so we can apply checksum on the
@@ -147,9 +170,9 @@ icmp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
// csum = ip_csum_add_even (csum, addr_new->ip6.as_u64[0]);
// csum = ip_csum_add_even (csum, addr_new->ip6.as_u64[1]);
//
- // csum = ip_csum_sub_even (csum, h->icmp.pathlabel);
- // icmp_update_data_pathlabel(type, h, face_id);
- // csum = ip_csum_add_even (csum, h->icmp.pathlabel);
+ // csum = ip_csum_sub_even (csum, icmp->path_label);
+ // icmp_update_data_path_label(pkbuf, pos, face_id);
+ // csum = ip_csum_add_even (csum, icmp->path_label);
//
// *icmp_checksum = ip_csum_fold (csum);
//
@@ -157,96 +180,92 @@ icmp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
}
int
-icmp_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+icmp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type)
{
- *header_length = ICMP_HDRLEN;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (get_type, pkbuf, pos, type);
}
int
-icmp_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+icmp_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
-
- *header_length = ICMP_HDRLEN + child_header_length;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_type, pkbuf, pos, type);
}
int
-icmp_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
+icmp_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *signature_size)
{
- return CHILD_OPS (get_signature_size, type, h, signature_size);
+ return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size);
}
int
-icmp_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
+icmp_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t signature_size)
{
- return CHILD_OPS (set_signature_size, type, h, signature_size);
+ return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size);
}
int
-icmp_set_signature_padding (hicn_type_t type, hicn_protocol_t *h,
+icmp_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t padding)
{
- return CHILD_OPS (set_signature_padding, type, h, padding);
+ return CALL_CHILD (set_signature_padding, pkbuf, pos, padding);
}
int
-icmp_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
+icmp_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *padding)
{
- return CHILD_OPS (get_signature_padding, type, h, padding);
+ return CALL_CHILD (get_signature_padding, pkbuf, pos, padding);
}
int
-icmp_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
+icmp_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t signature_timestamp)
{
- return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-icmp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
+icmp_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t *signature_timestamp)
{
- return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-icmp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
+icmp_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t validation_algorithm)
{
- return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (set_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-icmp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
+icmp_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t *validation_algorithm)
{
- return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (get_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-icmp_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+icmp_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *key_id, size_t key_len)
{
- return CHILD_OPS (set_key_id, type, h, key_id);
+ return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len);
}
int
-icmp_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size)
+icmp_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size)
{
- return CHILD_OPS (get_key_id, type, h, key_id, key_id_size);
+ return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size);
}
-DECLARE_HICN_OPS (icmp);
+DECLARE_HICN_OPS (icmp, ICMP_HDRLEN);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/lib/src/protocol/icmp.h b/lib/src/protocol/icmp.h
new file mode 100644
index 000000000..6cbba6398
--- /dev/null
+++ b/lib/src/protocol/icmp.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+/**
+ * @file protocol/icmp.h
+ * @brief ICMP packet header
+ */
+#ifndef HICN_PROTOCOL_ICMP_H
+#define HICN_PROTOCOL_ICMP_H
+
+#include <hicn/common.h>
+
+/*
+ * The length of the ICMP header struct must be 4 bytes.
+ */
+#define EXPECTED_ICMP_HDRLEN 4
+
+typedef struct
+{
+ u8 type;
+ u8 code;
+ u16 csum;
+} _icmp_header_t;
+
+#define ICMP_HDRLEN sizeof (_icmp_header_t)
+static_assert (EXPECTED_ICMP_HDRLEN == ICMP_HDRLEN,
+ "Size of ICMP struct does not match its expected size.");
+
+/*
+ * The length of the ICMPWLDR header struct must be 4 bytes.
+ */
+#define EXPECTED_ICMPWLDR_HDRLEN 8
+
+typedef struct
+{
+ u8 type;
+ u8 code;
+ u16 csum;
+ union
+ {
+ struct
+ {
+ u16 id;
+ u16 sequence;
+ } echo; /* echo datagram */
+ u32 gateway; /* gateway address */
+ struct
+ {
+ u16 _unused;
+ u16 mtu;
+ } frag; /* path mtu discovery */
+ struct
+ {
+ u16 expected_lbl;
+ u16 received_lbl;
+ } wldr_notification_lbl;
+ };
+} _icmp_wldr_header_t;
+
+#define ICMPWLDR_HDRLEN sizeof (_icmp_wldr_header_t)
+static_assert (EXPECTED_ICMPWLDR_HDRLEN == ICMPWLDR_HDRLEN,
+ "Size of ICMPWLDR struct does not match its expected size.");
+
+#endif /* HICN_PROTOCOL_ICMP_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/icmprd.h b/lib/src/protocol/icmprd.h
new file mode 100644
index 000000000..7edff8111
--- /dev/null
+++ b/lib/src/protocol/icmprd.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+/**
+ * @file protocol/icmp-rd.c
+ * @brief hICN operations for ICMP Redirect header
+ */
+#ifndef HICN_PROTOCOL_ICMPRD_H
+#define HICN_PROTOCOL_ICMPRD_H
+
+#include <hicn/common.h>
+#include "ipv4.h"
+
+/*
+ * The length of the ICMPRD4 header struct must be 92 bytes.
+ */
+#define EXPECTED_ICMPRD4_HDRLEN 92
+
+typedef struct
+{
+ u8 type;
+ u8 code;
+ u16 csum;
+ ipv4_address_t ip;
+ _ipv4_header_t iph;
+ u8 data[64];
+} _icmprd4_header_t;
+
+#define ICMPRD4_HDRLEN sizeof (_icmprd4_header_t)
+static_assert (EXPECTED_ICMPRD4_HDRLEN == ICMPRD4_HDRLEN,
+ "Size of ICMPWLDR struct does not match its expected size.");
+
+/*
+ * The length of the ICMPRD header struct must be 40 bytes.
+ */
+#define EXPECTED_ICMPRD_HDRLEN 40
+
+typedef struct
+{
+ u8 type;
+ u8 code;
+ u16 csum;
+ u32 res;
+ ipv6_address_t tgt;
+ ipv6_address_t dst;
+} _icmprd_header_t;
+
+#define ICMPRD_HDRLEN sizeof (_icmprd_header_t)
+static_assert (EXPECTED_ICMPRD_HDRLEN == ICMPRD_HDRLEN,
+ "Size of ICMPWLDR struct does not match its expected size.");
+
+#endif /* HICN_PROTOCOL_ICMPRD_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/ipv4.c b/lib/src/protocol/ipv4.c
index 840fbe34b..a13728d04 100644
--- a/lib/src/protocol/ipv4.c
+++ b/lib/src/protocol/ipv4.c
@@ -14,7 +14,7 @@
*/
/**
- * @file protocol/ipv4.c
+ * @file protocol/ipv4->c
* @brief hICN operations for IPv4 header
*
* NOTE: IPv4 options (affecting the header size) are currently not supported.
@@ -28,264 +28,262 @@
#include <string.h>
#include <hicn/error.h>
-#include <hicn/ops.h>
#include <hicn/common.h>
-#include <hicn/header.h>
-#include <hicn/protocol/ipv4.h>
-typedef unsigned short u_short;
-int ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *payload_length);
+#include "../ops.h"
+#include "ipv4.h"
+
+#define UINT16_T_MASK 0x0000ffff // 1111 1111 1111 1111
+
+#define ipv4_get_payload_len(pkbuf, ipv4) htons (ipv4->len - pkbuf->payload)
int
-ipv4_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+ipv4_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- size_t total_header_length;
- int rc =
- hicn_ops_vft[type.l1]->get_header_length (type, h, &total_header_length);
- if (rc < 0)
- return rc;
+ assert (pkbuf->len == 0);
+ if (IPV4_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += IPV4_HDRLEN;
+
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ hicn_packet_format_t format = hicn_packet_get_format (pkbuf);
- h->ipv4 = (_ipv4_header_t){
+ size_t header_len;
+ hicn_packet_get_header_length_from_format (pkbuf->format, &header_len);
+
+ /* We initialize the len considering an empty payload */
+ *ipv4 = (_ipv4_header_t){
.version_ihl = (IPV4_DEFAULT_VERSION << 4) | (0x0f & IPV4_DEFAULT_IHL),
.tos = IPV4_DEFAULT_TOS,
- .len = htons ((u16) total_header_length),
+ .len = htons (header_len),
.id = htons (IPV4_DEFAULT_ID),
.frag_off = htons (IPV4_DEFAULT_FRAG_OFF),
.ttl = HICN_DEFAULT_TTL,
- .protocol = type.l2,
+ .protocol = format.as_u8[pos + 1],
.csum = 0,
.saddr.as_u32 = 0,
.daddr.as_u32 = 0,
};
- return CHILD_OPS (init_packet_header, type, h);
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-ipv4_get_interest_locator (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address)
+ipv4_get_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_ip_address_t *ip_address)
{
- ip_address->v4 = h->ipv4.saddr;
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ip_address->v4 = ipv4->saddr;
return HICN_LIB_ERROR_NONE;
}
int
-ipv4_set_interest_locator (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address)
+ipv4_set_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address)
{
- h->ipv4.saddr = ip_address->v4;
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ipv4->saddr = ip_address->v4;
return HICN_LIB_ERROR_NONE;
}
int
-ipv4_get_interest_name (hicn_type_t type, const hicn_protocol_t *h,
+ipv4_get_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_t *name)
{
- name->prefix.v4 = h->ipv4.daddr;
- return CHILD_OPS (get_interest_name_suffix, type, h, &(name->suffix));
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ name->prefix.v4 = ipv4->daddr;
+ return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv4_set_interest_name (hicn_type_t type, hicn_protocol_t *h,
+ipv4_set_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_t *name)
{
- h->ipv4.daddr = name->prefix.v4;
- return CHILD_OPS (set_interest_name_suffix, type, h, &(name->suffix));
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ipv4->daddr = name->prefix.v4;
+ return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv4_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+ipv4_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (get_interest_name_suffix, type, h, suffix);
+ return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, suffix);
}
int
-ipv4_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+ipv4_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (set_interest_name_suffix, type, h, suffix);
+ return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, suffix);
}
int
-ipv4_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest)
+ipv4_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type)
{
- return CHILD_OPS (is_interest, type, h, is_interest);
+ return CALL_CHILD (get_type, pkbuf, pos, type);
}
int
-ipv4_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h)
+ipv4_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type)
{
- return CHILD_OPS (mark_packet_as_interest, type, h);
+ return CALL_CHILD (set_type, pkbuf, pos, type);
}
int
-ipv4_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h)
+ipv4_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- return CHILD_OPS (mark_packet_as_data, type, h);
-}
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
-int
-ipv4_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
-{
/* Sets everything to 0 up to IP destination address */
- memset (&(h->ipv4), 0, 16);
+ memset (ipv4, 0, 16);
- return CHILD_OPS (reset_interest_for_hash, type, h);
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-ipv4_get_data_locator (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address)
+ipv4_get_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_ip_address_t *ip_address)
{
- ip_address->v4 = h->ipv4.daddr;
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ip_address->v4 = ipv4->daddr;
return HICN_LIB_ERROR_NONE;
}
int
-ipv4_set_data_locator (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address)
+ipv4_set_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address)
{
- h->ipv4.daddr = ip_address->v4;
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ipv4->daddr = ip_address->v4;
return HICN_LIB_ERROR_NONE;
}
int
-ipv4_get_data_name (hicn_type_t type, const hicn_protocol_t *h,
+ipv4_get_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_t *name)
{
- name->prefix.v4 = h->ipv4.saddr;
- return CHILD_OPS (get_data_name_suffix, type, h, &(name->suffix));
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ name->prefix.v4 = ipv4->saddr;
+ return CALL_CHILD (get_data_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv4_set_data_name (hicn_type_t type, hicn_protocol_t *h,
+ipv4_set_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_t *name)
{
- h->ipv4.saddr = name->prefix.v4;
- return CHILD_OPS (set_data_name_suffix, type, h, &(name->suffix));
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ipv4->saddr = name->prefix.v4;
+ return CALL_CHILD (set_data_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv4_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+ipv4_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (get_data_name_suffix, type, h, suffix);
+ return CALL_CHILD (get_data_name_suffix, pkbuf, pos, suffix);
}
int
-ipv4_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+ipv4_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (set_data_name_suffix, type, h, suffix);
+ return CALL_CHILD (set_data_name_suffix, pkbuf, pos, suffix);
}
int
-ipv4_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h,
- u32 *pathlabel)
+ipv4_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t *path_label)
{
- return CHILD_OPS (get_data_pathlabel, type, h, pathlabel);
+ return CALL_CHILD (get_data_path_label, pkbuf, pos, path_label);
}
int
-ipv4_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const u32 pathlabel)
+ipv4_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t path_label)
{
- return CHILD_OPS (set_data_pathlabel, type, h, pathlabel);
+ return CALL_CHILD (set_data_path_label, pkbuf, pos, path_label);
}
int
-ipv4_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const hicn_faceid_t face_id)
+ipv4_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_faceid_t face_id)
{
- return CHILD_OPS (update_data_pathlabel, type, h, face_id);
+ return CALL_CHILD (update_data_path_label, pkbuf, pos, face_id);
}
int
-ipv4_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+ipv4_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
/* Sets everything to 0 up to source address */
- memset (&h->ipv4, 0, 12);
+ memset (ipv4, 0, 12);
/* Clears destination address */
- memset (&(h->ipv4.daddr), 0, 4);
+ memset (&(ipv4->daddr), 0, 4);
- return CHILD_OPS (reset_data_for_hash, type, h);
+ return CALL_CHILD (reset_data_for_hash, pkbuf, pos);
}
int
-ipv4_get_lifetime (hicn_type_t type, const hicn_protocol_t *h,
+ipv4_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_lifetime_t *lifetime)
{
- return CHILD_OPS (get_lifetime, type, h, lifetime);
+ return CALL_CHILD (get_lifetime, pkbuf, pos, lifetime);
}
int
-ipv4_set_lifetime (hicn_type_t type, hicn_protocol_t *h,
+ipv4_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_lifetime_t lifetime)
{
- return CHILD_OPS (set_lifetime, type, h, lifetime);
-}
-
-int
-ipv4_get_source_port (hicn_type_t type, const hicn_protocol_t *h,
- u16 *source_port)
-{
- return CHILD_OPS (get_source_port, type, h, source_port);
-}
-
-int
-ipv4_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port)
-{
- return CHILD_OPS (get_dest_port, type, h, dest_port);
-}
-
-int
-ipv4_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port)
-{
- return CHILD_OPS (set_source_port, type, h, source_port);
+ return CALL_CHILD (set_lifetime, pkbuf, pos, lifetime);
}
int
-ipv4_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port)
+ipv4_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- return CHILD_OPS (set_dest_port, type, h, dest_port);
-}
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
-int
-ipv4_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
-{
/*
* Checksum field is not accounted for in lower layers, so we can compute
* them in any order. Note that it is only a header checksum.
*/
- h->ipv4.csum = 0;
- h->ipv4.csum = csum (h, IPV4_HDRLEN, 0);
+ ipv4->csum = 0;
+ ipv4->csum = csum (pkbuf_get_header (pkbuf), IPV4_HDRLEN, 0);
- /* Retrieve payload length if not specified, as it is not available later */
- if (payload_length == 0)
+ /* Retrieve payload len if not specified, as it is not available later */
+ if (payload_len == 0)
{
- int rc = ipv4_get_payload_length (type, h, &payload_length);
- if (rc < 0)
- return rc;
+ payload_len = ipv4_get_payload_len (pkbuf, ipv4);
}
- /* Ignore the payload if payload_length = ~0 */
- if (payload_length == ~0)
+ /* Ignore the payload if payload_len = ~0 */
+ if (payload_len == ~0)
{
- payload_length = 0;
+ payload_len = 0;
}
/* Build pseudo-header */
ipv4_pseudo_header_t psh;
- psh.ip_src = h->ipv4.saddr;
- psh.ip_dst = h->ipv4.daddr;
+ psh.ip_src = ipv4->saddr;
+ psh.ip_dst = ipv4->daddr;
/* Size is u32 and not u16, we cannot copy and need to care about endianness
*/
- psh.size = htons (ntohs (h->ipv4.len) - (u16) IPV4_HDRLEN);
+ psh.size = htons (ntohs (ipv4->len) - (u16) IPV4_HDRLEN);
psh.zero = 0;
- psh.protocol = (u8) h->ipv4.protocol;
+ psh.protocol = (u8) ipv4->protocol;
/* Compute partial checksum based on pseudo-header */
if (partial_csum != 0)
@@ -294,243 +292,289 @@ ipv4_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
}
partial_csum = csum (&psh, IPV4_PSHDRLEN, partial_csum);
- return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length);
+ return CALL_CHILD (update_checksums, pkbuf, pos, partial_csum, payload_len);
+}
+
+int
+ipv4_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first)
+{
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ /* We update the child first */
+ int rc = CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val,
+ new_val, size, false);
+ if (rc < 0)
+ return rc;
+
+ if (!skip_first)
+ {
+ for (uint8_t i = 0; i < size; i++)
+ {
+ uint16_t old_csum = ~ipv4->csum;
+ uint16_t not_old_val = ~(*old_val);
+ uint32_t sum = (uint32_t) old_csum + not_old_val + *new_val;
+
+ while (sum >> 16)
+ {
+ sum = (sum >> 16) + (sum & UINT16_T_MASK);
+ }
+
+ ipv4->csum = ~sum;
+ ++old_val;
+ ++new_val;
+ }
+ }
+
+ return HICN_LIB_ERROR_NONE;
}
int
-ipv4_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+ipv4_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
/*
* Checksum field is not accounted for in lower layers, so we can compute
* them in any order. Note that it is only a header checksum.
*/
- if (csum (h, IPV4_HDRLEN, 0) != 0)
+ if (csum (pkbuf_get_header (pkbuf), IPV4_HDRLEN, 0) != 0)
return HICN_LIB_ERROR_CORRUPTED_PACKET;
- /* Retrieve payload length if not specified, as it is not available later */
- if (payload_length == 0)
+ /* Retrieve payload len if not specified, as it is not available later */
+ if (payload_len == 0)
{
- int rc = ipv4_get_payload_length (type, h, &payload_length);
- if (rc < 0)
- return rc;
+ payload_len = ipv4_get_payload_len (pkbuf, ipv4);
}
/* Build pseudo-header */
ipv4_pseudo_header_t psh;
- psh.ip_src = h->ipv4.saddr;
- psh.ip_dst = h->ipv4.daddr;
+ psh.ip_src = ipv4->saddr;
+ psh.ip_dst = ipv4->daddr;
/* Size is u32 and not u16, we cannot copy and need to care about endianness
*/
- psh.size = htons (ntohs (h->ipv4.len) - (u16) IPV4_HDRLEN);
+ psh.size = htons (ntohs (ipv4->len) - (u16) IPV4_HDRLEN);
psh.zero = 0;
- psh.protocol = (u8) h->ipv4.protocol;
+ psh.protocol = (u8) ipv4->protocol;
/* Compute partial checksum based on pseudo-header */
partial_csum = csum (&psh, IPV4_PSHDRLEN, 0);
- return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length);
+ return CALL_CHILD (verify_checksums, pkbuf, pos, partial_csum, payload_len);
}
int
-ipv4_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+ipv4_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
// ASSERT(addr_old == NULL);
- addr_old->v4 = h->ipv4.saddr;
+ addr_old->v4 = ipv4->saddr;
addr_old->pad[0] = 0;
addr_old->pad[1] = 0;
addr_old->pad[2] = 0;
- h->ipv4.saddr = addr_new->v4;
- h->ipv4.csum = 0;
- h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0);
+ ipv4->saddr = addr_new->v4;
+ ipv4->csum = 0;
+ ipv4->csum = csum (&ipv4, IPV4_HDRLEN, 0);
- return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old);
+ return CALL_CHILD (rewrite_interest, pkbuf, pos, addr_new, addr_old);
}
int
-ipv4_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+ipv4_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
// ASSERT(addr_old == NULL);
- addr_old->v4 = h->ipv4.daddr;
+ addr_old->v4 = ipv4->daddr;
addr_old->pad[0] = 0;
addr_old->pad[1] = 0;
addr_old->pad[2] = 0;
- h->ipv4.daddr = addr_new->v4;
- h->ipv4.csum = 0;
- h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0);
+ ipv4->daddr = addr_new->v4;
+ ipv4->csum = 0;
+ ipv4->csum = csum (&ipv4, IPV4_HDRLEN, 0);
- return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id,
- reset_pl);
+ return CALL_CHILD (rewrite_data, pkbuf, pos, addr_new, addr_old, face_id,
+ reset_pl);
}
int
-ipv4_get_current_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv4_set_payload_len (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t payload_len)
{
- *header_length = IPV4_HDRLEN;
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ size_t child_header_len = hicn_ops_vft[pos + 1]->header_len;
+
+ ipv4->len = htons ((u16) (payload_len + IPV4_HDRLEN + child_header_len));
return HICN_LIB_ERROR_NONE;
}
int
-ipv4_get_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv4_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t *payload_type)
{
- *header_length = h->ipv4.len;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (get_payload_type, pkbuf, pos, payload_type);
}
int
-ipv4_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv4_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t payload_type)
{
- *header_length = IPV4_HDRLEN;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_payload_type, pkbuf, pos, payload_type);
}
int
-ipv4_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv4_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t *signature_size)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *header_length = IPV4_HDRLEN + child_header_length;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size);
}
int
-ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *payload_length)
+ipv4_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t signature_size)
{
- size_t child_header_length;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *payload_length = htons (h->ipv4.len) - IPV4_HDRLEN - child_header_length;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size);
}
int
-ipv4_set_payload_length (hicn_type_t type, hicn_protocol_t *h,
- size_t payload_length)
+ipv4_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t padding)
{
- size_t child_header_length;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- h->ipv4.len =
- htons ((u_short) (payload_length + IPV4_HDRLEN + child_header_length));
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_signature_padding, pkbuf, pos, padding);
}
int
-ipv4_get_payload_type (hicn_type_t type, const hicn_protocol_t *h,
- hicn_payload_type_t *payload_type)
+ipv4_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t *padding)
{
- return CHILD_OPS (get_payload_type, type, h, payload_type);
+ return CALL_CHILD (get_signature_padding, pkbuf, pos, padding);
}
int
-ipv4_set_payload_type (hicn_type_t type, hicn_protocol_t *h,
- hicn_payload_type_t payload_type)
+ipv4_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint64_t signature_timestamp)
{
- return CHILD_OPS (set_payload_type, type, h, payload_type);
+ return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-ipv4_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
- size_t *signature_size)
+ipv4_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint64_t *signature_timestamp)
{
- return CHILD_OPS (get_signature_size, type, h, signature_size);
+ return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-ipv4_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
- size_t signature_size)
+ipv4_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t validation_algorithm)
{
- return CHILD_OPS (set_signature_size, type, h, signature_size);
+ return CALL_CHILD (set_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-ipv4_set_signature_padding (hicn_type_t type, hicn_protocol_t *h,
- size_t padding)
+ipv4_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *validation_algorithm)
{
- return CHILD_OPS (set_signature_padding, type, h, padding);
+ return CALL_CHILD (get_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-ipv4_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
- size_t *padding)
+ipv4_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *key_id, size_t key_len)
{
- return CHILD_OPS (get_signature_padding, type, h, padding);
+ return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len);
}
int
-ipv4_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
- uint64_t signature_timestamp)
+ipv4_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size)
{
- return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size);
}
int
-ipv4_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
- uint64_t *signature_timestamp)
+ipv4_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **signature)
{
- return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_signature, pkbuf, pos, signature);
}
int
-ipv4_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
- uint8_t validation_algorithm)
+ipv4_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag)
{
- return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (has_signature, pkbuf, pos, flag);
}
int
-ipv4_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
- uint8_t *validation_algorithm)
+ipv4_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last)
+{
+ return CALL_CHILD (is_last_data, pkbuf, pos, is_last);
+}
+
+int
+ipv4_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos)
+{
+ return CALL_CHILD (set_last_data, pkbuf, pos);
+}
+
+int
+ipv4_get_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 *hops)
{
- return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ *hops = ipv4->ttl;
+
+ return HICN_LIB_ERROR_NONE;
}
int
-ipv4_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+ipv4_set_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 hops)
{
- return CHILD_OPS (set_key_id, type, h, key_id);
+ _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf);
+
+ ipv4->ttl = hops;
+
+ return HICN_LIB_ERROR_NONE;
}
int
-ipv4_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size)
+ipv4_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- return CHILD_OPS (get_key_id, type, h, key_id, key_id_size);
+ return CALL_CHILD (get_src_port, pkbuf, pos, port);
}
int
-ipv4_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature)
+ipv4_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- return CHILD_OPS (get_signature, type, h, signature);
+ return CALL_CHILD (set_src_port, pkbuf, pos, port);
}
int
-ipv4_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last)
+ipv4_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- return CHILD_OPS (is_last_data, type, h, is_last);
+ return CALL_CHILD (get_dst_port, pkbuf, pos, port);
}
int
-ipv4_set_last_data (hicn_type_t type, hicn_protocol_t *h)
+ipv4_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- return CHILD_OPS (set_last_data, type, h);
+ return CALL_CHILD (set_dst_port, pkbuf, pos, port);
}
-DECLARE_HICN_OPS (ipv4);
+DECLARE_HICN_OPS (ipv4, IPV4_HDRLEN);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/lib/src/protocol/ipv4.h b/lib/src/protocol/ipv4.h
new file mode 100644
index 000000000..5d729b955
--- /dev/null
+++ b/lib/src/protocol/ipv4.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+#ifndef HICN_PROTOCOL_IPV4
+#define HICN_PROTOCOL_IPV4
+
+#include <hicn/util/ip_address.h>
+
+#include <hicn/base.h>
+#include <hicn/common.h>
+
+/* Headers were adapted from linux' definitions in netinet/ip.h */
+
+/*
+ * The length of the IPV4 header struct must be 20 bytes.
+ */
+#define EXPECTED_IPV4_HDRLEN 20
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ u8 ihl : 4;
+ u8 version : 4;
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ u8 version : 4;
+ u8 ihl : 4;
+#else
+#error "Unsupported endianness"
+#endif
+ };
+
+ u8 version_ihl;
+ };
+ u8 tos;
+
+ /*
+ * This is the total length of the IP packet, including the IP header.
+ * NOTE: vriable len header size is currently not supported by the lib.
+ */
+ u16 len;
+
+ u16 id;
+ u16 frag_off;
+ u8 ttl;
+ u8 protocol;
+ u16 csum;
+ ipv4_address_t saddr;
+ ipv4_address_t daddr;
+} _ipv4_header_t;
+
+#define ipv4_header_bytes(ipv4_header) \
+ (sizeof (u32) * (ipv4_header->version_ihl & 0xf))
+
+#define IPV4_HDRLEN sizeof (_ipv4_header_t)
+static_assert (EXPECTED_IPV4_HDRLEN == IPV4_HDRLEN,
+ "Size of IPV4 struct does not match its expected size.");
+
+/*
+ * The length of the IPV4 pseudo header struct must be 12 bytes.
+ */
+#define EXPECTED_IPV4_PSHDRLEN 12
+
+typedef struct
+{
+ ipv4_address_t ip_src;
+ ipv4_address_t ip_dst;
+ u8 zero;
+ u8 protocol;
+ u16 size;
+} ipv4_pseudo_header_t;
+
+#define IPV4_PSHDRLEN sizeof (ipv4_pseudo_header_t)
+static_assert (EXPECTED_IPV4_PSHDRLEN == IPV4_PSHDRLEN,
+ "Size of IPV4_PSHDR struct does not match its expected size.");
+
+/* Default field values */
+#define IPV4_DEFAULT_VERSION 4
+#define IPV4_DEFAULT_IHL 5
+#define IPV4_DEFAULT_TOS 0
+#define IPV4_DEFAULT_PAYLOAD_LENGTH 0
+#define IPV4_DEFAULT_ID 300
+#define IPV4_DEFAULT_FRAG_OFF 0x000
+#define IPV4_DEFAULT_TTL 64
+#define IPV4_DEFAULT_PROTOCOL IPPROTO_TCP
+#define IPV4_DEFAULT_SRC_IP 0, 0, 0, 0
+#define IPV4_DEFAULT_DST_IP 0, 0, 0, 0
+
+#endif /* HICN_PROTOCOL_IPV4 */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/ipv6.c b/lib/src/protocol/ipv6.c
index b3c543249..aec521afc 100644
--- a/lib/src/protocol/ipv6.c
+++ b/lib/src/protocol/ipv6.c
@@ -17,247 +17,252 @@
#include <string.h>
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/ops.h>
+
+#include "ipv6.h"
+#include "../ops.h"
typedef unsigned short u_short;
-int ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *payload_length);
+
+#ifdef OPAQUE_IP
+#define GET_IPV6_HEADER(pkbuf) \
+ (_ipv6_header_t *) ((pkbuf)->header + (pkbuf)->ipv6)
+#else
+#define GET_IPV6_HEADER(pkbuf) (_ipv6_header_t *) ((pkbuf)->header)
+#endif /* OPAQUE_IP */
int
-ipv6_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+ipv6_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- size_t total_header_length;
- int rc = CHILD_OPS (get_header_length, type, h, &total_header_length);
- if (rc < 0)
- return rc;
+ assert (pkbuf->len == 0);
+ if (IPV6_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += IPV6_HDRLEN;
+
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
- /* *INDENT-OFF* */
- h->ipv6 = (_ipv6_header_t){
+ hicn_packet_format_t format = hicn_packet_get_format (pkbuf);
+
+ size_t header_len;
+ hicn_packet_get_header_length_from_format (pkbuf->format, &header_len);
+
+ /* clang-format off */
+ *ipv6 = (_ipv6_header_t){
.saddr = IP6_ADDRESS_EMPTY,
.daddr = IP6_ADDRESS_EMPTY,
.version_class_flow = htonl ((IPV6_DEFAULT_VERSION << 28) |
(IPV6_DEFAULT_TRAFFIC_CLASS << 20) |
(IPV6_DEFAULT_FLOW_LABEL & 0xfffff)),
- .len = htons ((u16) total_header_length),
- .nxt = type.l2,
+ .len = htons(header_len - IPV6_HDRLEN),
+ .nxt = format.as_u8[pos + 1],
.hlim = HICN_DEFAULT_TTL,
};
- /* *INDENT-ON* */
- return CHILD_OPS (init_packet_header, type, h);
+ /* clang-format on */
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-ipv6_get_interest_locator (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address)
+ipv6_get_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_ip_address_t *ip_address)
{
- ip_address->v6 = h->ipv6.saddr;
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ip_address->v6 = ipv6->saddr;
return HICN_LIB_ERROR_NONE;
}
int
-ipv6_set_interest_locator (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address)
+ipv6_set_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address)
{
- h->ipv6.saddr = ip_address->v6;
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ipv6->saddr = ip_address->v6;
return HICN_LIB_ERROR_NONE;
}
int
-ipv6_get_interest_name (hicn_type_t type, const hicn_protocol_t *h,
+ipv6_get_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_t *name)
{
- name->prefix.v6 = h->ipv6.daddr;
- return CHILD_OPS (get_interest_name_suffix, type, h, &(name->suffix));
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ name->prefix.v6 = ipv6->daddr;
+ return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv6_set_interest_name (hicn_type_t type, hicn_protocol_t *h,
+ipv6_set_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_t *name)
{
- h->ipv6.daddr = name->prefix.v6;
- return CHILD_OPS (set_interest_name_suffix, type, h, &(name->suffix));
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ipv6->daddr = name->prefix.v6;
+ return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv6_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+ipv6_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (get_interest_name_suffix, type, h, suffix);
+ return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, suffix);
}
int
-ipv6_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+ipv6_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (set_interest_name_suffix, type, h, suffix);
+ return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, suffix);
}
int
-ipv6_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest)
+ipv6_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type)
{
- return CHILD_OPS (is_interest, type, h, is_interest);
+ return CALL_CHILD (get_type, pkbuf, pos, type);
}
int
-ipv6_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h)
+ipv6_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type)
{
- return CHILD_OPS (mark_packet_as_interest, type, h);
+ return CALL_CHILD (set_type, pkbuf, pos, type);
}
int
-ipv6_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h)
+ipv6_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- return CHILD_OPS (mark_packet_as_data, type, h);
-}
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
-int
-ipv6_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
-{
/* Sets everything to 0 up to IP destination address */
- memset (&(h->ipv6), 0, 24);
+ memset (ipv6, 0, 24);
- return CHILD_OPS (reset_interest_for_hash, type, h);
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-ipv6_get_data_locator (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address)
+ipv6_get_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_ip_address_t *ip_address)
{
- ip_address->v6 = h->ipv6.daddr;
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ip_address->v6 = ipv6->daddr;
return HICN_LIB_ERROR_NONE;
}
int
-ipv6_set_data_locator (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address)
+ipv6_set_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address)
{
- h->ipv6.daddr = ip_address->v6;
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ipv6->daddr = ip_address->v6;
return HICN_LIB_ERROR_NONE;
}
int
-ipv6_get_data_name (hicn_type_t type, const hicn_protocol_t *h,
+ipv6_get_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_t *name)
{
- name->prefix.v6 = h->ipv6.saddr;
- return CHILD_OPS (get_data_name_suffix, type, h, &(name->suffix));
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ name->prefix.v6 = ipv6->saddr;
+ return CALL_CHILD (get_data_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv6_set_data_name (hicn_type_t type, hicn_protocol_t *h,
+ipv6_set_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_t *name)
{
- h->ipv6.saddr = name->prefix.v6;
- return CHILD_OPS (set_data_name_suffix, type, h, &(name->suffix));
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ipv6->saddr = name->prefix.v6;
+ return CALL_CHILD (set_data_name_suffix, pkbuf, pos, &(name->suffix));
}
int
-ipv6_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+ipv6_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (get_data_name_suffix, type, h, suffix);
+ return CALL_CHILD (get_data_name_suffix, pkbuf, pos, suffix);
}
int
-ipv6_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+ipv6_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (set_data_name_suffix, type, h, suffix);
+ return CALL_CHILD (set_data_name_suffix, pkbuf, pos, suffix);
}
int
-ipv6_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h,
- u32 *pathlabel)
+ipv6_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t *path_label)
{
- return CHILD_OPS (get_data_pathlabel, type, h, pathlabel);
+ return CALL_CHILD (get_data_path_label, pkbuf, pos, path_label);
}
int
-ipv6_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const u32 pathlabel)
+ipv6_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t path_label)
{
- return CHILD_OPS (set_data_pathlabel, type, h, pathlabel);
+ return CALL_CHILD (set_data_path_label, pkbuf, pos, path_label);
}
int
-ipv6_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const hicn_faceid_t face_id)
+ipv6_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_faceid_t face_id)
{
- return CHILD_OPS (update_data_pathlabel, type, h, face_id);
+ return CALL_CHILD (update_data_path_label, pkbuf, pos, face_id);
}
int
-ipv6_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+ipv6_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
/* IP: Set everithing to 0 up to destination address */
- memset (&h->ipv6, 0, 8);
+ memset (ipv6, 0, 8);
/* Clears destination address */
- memset (&(h->ipv6.daddr), 0, 16);
+ memset (&(ipv6->daddr), 0, 16);
- return CHILD_OPS (reset_data_for_hash, type, h);
+ return CALL_CHILD (reset_data_for_hash, pkbuf, pos);
}
int
-ipv6_get_lifetime (hicn_type_t type, const hicn_protocol_t *h,
+ipv6_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_lifetime_t *lifetime)
{
- return CHILD_OPS (get_lifetime, type, h, lifetime);
+ return CALL_CHILD (get_lifetime, pkbuf, pos, lifetime);
}
int
-ipv6_set_lifetime (hicn_type_t type, hicn_protocol_t *h,
+ipv6_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_lifetime_t lifetime)
{
- return CHILD_OPS (set_lifetime, type, h, lifetime);
-}
-
-int
-ipv6_get_source_port (hicn_type_t type, const hicn_protocol_t *h,
- u16 *source_port)
-{
- return CHILD_OPS (get_source_port, type, h, source_port);
+ return CALL_CHILD (set_lifetime, pkbuf, pos, lifetime);
}
int
-ipv6_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port)
+ipv6_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- return CHILD_OPS (get_dest_port, type, h, dest_port);
-}
-
-int
-ipv6_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port)
-{
- return CHILD_OPS (set_source_port, type, h, source_port);
-}
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
-int
-ipv6_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port)
-{
- return CHILD_OPS (set_dest_port, type, h, dest_port);
-}
-
-int
-ipv6_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
-{
- /* Retrieve payload length if not specified */
- if (payload_length == ~0)
+ /* Retrieve payload len if not specified */
+ if (payload_len == ~0)
{
- int rc = ipv6_get_payload_length (type, h, &payload_length);
- if (rc < 0)
- return rc;
+ payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload;
}
/* Build pseudo-header */
ipv6_pseudo_header_t psh;
- psh.ip_src = h->ipv6.saddr;
- psh.ip_dst = h->ipv6.daddr;
+ psh.ip_src = ipv6->saddr;
+ psh.ip_dst = ipv6->daddr;
/* Size is u32 and not u16, we cannot copy and need to care about endianness
*/
- psh.size = htonl (ntohs (h->ipv6.len));
+ psh.size = htonl (ntohs (ipv6->len));
psh.zeros = 0;
psh.zero = 0;
- psh.protocol = h->ipv6.nxt;
+ psh.protocol = ipv6->nxt;
/* Compute partial checksum based on pseudo-header */
if (partial_csum != 0)
@@ -266,31 +271,41 @@ ipv6_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
}
partial_csum = csum (&psh, IPV6_PSHDRLEN, partial_csum);
- return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length);
+ return CALL_CHILD (update_checksums, pkbuf, pos, partial_csum, payload_len);
}
int
-ipv6_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+ipv6_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first)
{
- /* Retrieve payload length if not specified */
- if (payload_length == ~0)
+ /* We update the child only */
+ return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val,
+ new_val, size, false);
+}
+
+int
+ipv6_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
+{
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ /* Retrieve payload len if not specified */
+ if (payload_len == ~0)
{
- int rc = ipv6_get_payload_length (type, h, &payload_length);
- if (rc < 0)
- return rc;
+ payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload;
}
/* Build pseudo-header */
ipv6_pseudo_header_t pseudo;
- pseudo.ip_src = h->ipv6.saddr;
- pseudo.ip_dst = h->ipv6.daddr;
+ pseudo.ip_src = ipv6->saddr;
+ pseudo.ip_dst = ipv6->daddr;
/* Size is u32 and not u16, we cannot copy and need to care about endianness
*/
- pseudo.size = htonl (ntohs (h->ipv6.len));
+ pseudo.size = htonl (ntohs (ipv6->len));
pseudo.zeros = 0;
pseudo.zero = 0;
- pseudo.protocol = h->ipv6.nxt;
+ pseudo.protocol = ipv6->nxt;
/* Compute partial checksum based on pseudo-header */
if (partial_csum != 0)
@@ -299,187 +314,206 @@ ipv6_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
}
partial_csum = csum (&pseudo, IPV6_PSHDRLEN, partial_csum);
- return CHILD_OPS (verify_checksums, type, h, partial_csum, payload_length);
+ return CALL_CHILD (verify_checksums, pkbuf, pos, partial_csum, payload_len);
}
int
-ipv6_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+ipv6_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
// ASSERT(addr_old == NULL);
- addr_old->v6 = h->ipv6.saddr;
- h->ipv6.saddr = addr_new->v6;
+ addr_old->v6 = ipv6->saddr;
+ ipv6->saddr = addr_new->v6;
- return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old);
+ return CALL_CHILD (rewrite_interest, pkbuf, pos, addr_new, addr_old);
}
int
-ipv6_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+ipv6_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
// ASSERT(addr_old == NULL);
- addr_old->v6 = h->ipv6.daddr;
- h->ipv6.daddr = addr_new->v6;
+ addr_old->v6 = ipv6->daddr;
+ ipv6->daddr = addr_new->v6;
- return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id,
- reset_pl);
+ return CALL_CHILD (rewrite_data, pkbuf, pos, addr_new, addr_old, face_id,
+ reset_pl);
}
int
-ipv6_get_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv6_set_payload_len (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t payload_len)
{
- *header_length = IPV6_HDRLEN + ntohs (h->ipv6.len);
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ipv6->len = htons ((u_short) (payload_len + pkbuf->payload - IPV6_HDRLEN));
return HICN_LIB_ERROR_NONE;
}
int
-ipv6_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv6_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t *payload_type)
{
- *header_length = IPV6_HDRLEN;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (get_payload_type, pkbuf, pos, payload_type);
}
int
-ipv6_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+ipv6_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t payload_type)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *header_length = IPV6_HDRLEN + child_header_length;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_payload_type, pkbuf, pos, payload_type);
}
int
-ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *payload_length)
+ipv6_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t *signature_size)
{
- size_t child_header_length;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *payload_length = ntohs (h->ipv6.len) - child_header_length;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size);
}
int
-ipv6_set_payload_length (hicn_type_t type, hicn_protocol_t *h,
- size_t payload_length)
+ipv6_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t signature_size)
{
- size_t child_header_length;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- h->ipv6.len = htons ((u_short) (payload_length + child_header_length));
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size);
}
int
-ipv6_get_payload_type (hicn_type_t type, const hicn_protocol_t *h,
- hicn_payload_type_t *payload_type)
+ipv6_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t padding)
{
- return CHILD_OPS (get_payload_type, type, h, payload_type);
+ return CALL_CHILD (set_signature_padding, pkbuf, pos, padding);
}
int
-ipv6_set_payload_type (hicn_type_t type, hicn_protocol_t *h,
- hicn_payload_type_t payload_type)
+ipv6_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t *padding)
{
- return CHILD_OPS (set_payload_type, type, h, payload_type);
+ return CALL_CHILD (get_signature_padding, pkbuf, pos, padding);
}
int
-ipv6_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
- size_t *signature_size)
+ipv6_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint64_t signature_timestamp)
{
- return CHILD_OPS (get_signature_size, type, h, signature_size);
+ return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-ipv6_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
- size_t signature_size)
+ipv6_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint64_t *signature_timestamp)
{
- return CHILD_OPS (set_signature_size, type, h, signature_size);
+ return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-ipv6_set_signature_padding (hicn_type_t type, hicn_protocol_t *h,
- size_t padding)
+ipv6_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t validation_algorithm)
{
- return CHILD_OPS (set_signature_padding, type, h, padding);
+ return CALL_CHILD (set_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-ipv6_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
- size_t *padding)
+ipv6_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *validation_algorithm)
{
- return CHILD_OPS (get_signature_padding, type, h, padding);
+ return CALL_CHILD (get_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-ipv6_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
- uint64_t signature_timestamp)
+ipv6_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *key_id, size_t key_len)
{
- return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len);
}
int
-ipv6_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
- uint64_t *signature_timestamp)
+ipv6_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size)
{
- return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size);
}
int
-ipv6_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
- uint8_t validation_algorithm)
+ipv6_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **signature)
{
- return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (get_signature, pkbuf, pos, signature);
}
int
-ipv6_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
- uint8_t *validation_algorithm)
+ipv6_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag)
+{
+ return CALL_CHILD (has_signature, pkbuf, pos, flag);
+}
+
+int
+ipv6_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last)
+{
+ return CALL_CHILD (is_last_data, pkbuf, pos, is_last);
+}
+
+int
+ipv6_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos)
+{
+ return CALL_CHILD (set_last_data, pkbuf, pos);
+}
+
+int
+ipv6_get_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 *hops)
{
- return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ *hops = ipv6->hlim;
+
+ return HICN_LIB_ERROR_NONE;
}
int
-ipv6_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+ipv6_set_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 hops)
{
- return CHILD_OPS (set_key_id, type, h, key_id);
+
+ _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf);
+
+ ipv6->hlim = hops;
+
+ return HICN_LIB_ERROR_NONE;
}
int
-ipv6_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size)
+ipv6_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- return CHILD_OPS (get_key_id, type, h, key_id, key_id_size);
+ return CALL_CHILD (get_src_port, pkbuf, pos, port);
}
int
-ipv6_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature)
+ipv6_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- return CHILD_OPS (get_signature, type, h, signature);
+ return CALL_CHILD (set_src_port, pkbuf, pos, port);
}
int
-ipv6_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last)
+ipv6_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- return CHILD_OPS (is_last_data, type, h, is_last);
+ return CALL_CHILD (get_dst_port, pkbuf, pos, port);
}
int
-ipv6_set_last_data (hicn_type_t type, hicn_protocol_t *h)
+ipv6_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- return CHILD_OPS (set_last_data, type, h);
+ return CALL_CHILD (set_dst_port, pkbuf, pos, port);
}
-DECLARE_HICN_OPS (ipv6);
+DECLARE_HICN_OPS (ipv6, IPV6_HDRLEN);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/lib/src/protocol/ipv6.h b/lib/src/protocol/ipv6.h
new file mode 100644
index 000000000..9a51096a0
--- /dev/null
+++ b/lib/src/protocol/ipv6.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+#ifndef HICN_PROTOCOL_IPV6_H
+#define HICN_PROTOCOL_IPV6_H
+
+#include <hicn/util/ip_address.h>
+
+#include <hicn/common.h>
+
+/*
+ * The length of the IPV6 header struct must be 40 bytes.
+ */
+#define EXPECTED_IPV6_HDRLEN 40
+
+typedef struct
+{
+#if 0 // TEMPORARY FIX
+ union
+ {
+ struct
+ {
+#endif
+ u32 version_class_flow; /* version, traffic class and 20 bits of flow-ID */
+ u16 len; /* payload length */
+ u8 nxt; /* next header */
+ u8 hlim; /* hop limit */
+#if 0
+ };
+ u8 vfc; /* 4 bits version, top 4 bits class */
+ };
+#endif
+ ipv6_address_t saddr; /* source address */
+ ipv6_address_t daddr; /* destination address */
+} _ipv6_header_t;
+
+#define IPV6_HDRLEN sizeof (_ipv6_header_t)
+static_assert (EXPECTED_IPV6_HDRLEN == IPV6_HDRLEN,
+ "Size of IPV6 struct does not match its expected size.");
+
+/*
+ * The length of the IPV6 pseudo header struct must be 40 bytes.
+ */
+#define EXPECTED_IPV6_PSHDRLEN 40
+
+typedef struct
+{
+ ipv6_address_t ip_src;
+ ipv6_address_t ip_dst;
+ u32 size;
+ u16 zeros;
+ u8 zero;
+ u8 protocol;
+} ipv6_pseudo_header_t;
+
+#define IPV6_PSHDRLEN sizeof (ipv6_pseudo_header_t)
+static_assert (EXPECTED_IPV6_PSHDRLEN == IPV6_PSHDRLEN,
+ "Size of IPV6_PSHDR struct does not match its expected size.");
+
+/* Default field values */
+#define IPV6_DEFAULT_VERSION 6
+#define IPV6_DEFAULT_TRAFFIC_CLASS 0
+#define IPV6_DEFAULT_FLOW_LABEL 0
+#define IPV6_DEFAULT_PAYLOAD_LENGTH 0
+
+#endif
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/new.c b/lib/src/protocol/new.c
index 07c1d0d76..5308e8c0a 100644
--- a/lib/src/protocol/new.c
+++ b/lib/src/protocol/new.c
@@ -17,423 +17,544 @@
#include <string.h>
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/ops.h>
+
+#include "udp.h"
+#include "../ops.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
-DECLARE_get_source_port (new, UNEXPECTED);
-DECLARE_get_dest_port (new, UNEXPECTED);
-DECLARE_set_source_port (new, UNEXPECTED);
-DECLARE_set_dest_port (new, UNEXPECTED);
-
-static int
-is_interest (u8 flags)
-{
- return flags & HICN_NEW_FLAG_INT;
-}
+DECLARE_get_ttl (new, UNEXPECTED);
+DECLARE_set_ttl (new, UNEXPECTED);
+DECLARE_get_src_port (new, UNEXPECTED);
+DECLARE_set_src_port (new, UNEXPECTED);
+DECLARE_get_dst_port (new, UNEXPECTED);
+DECLARE_set_dst_port (new, UNEXPECTED);
int
-new_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+new_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- memset (&h->newhdr, 0, sizeof (h->newhdr));
- _set_new_header_version (&h->newhdr);
- uint8_t ah_flag = type.l2 == IPPROTO_AH ? HICN_NEW_FLAG_SIG : 0;
- h->newhdr.flags |= ah_flag;
+ pkbuf->newhdr = pkbuf->len;
+ if (NEW_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += NEW_HDRLEN;
- return CHILD_OPS (init_packet_header, type, h);
-}
+ _new_header_t *new = pkbuf_get_new (pkbuf);
-int
-new_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest)
-{
- *is_interest = (h->newhdr.flags & HICN_NEW_FLAG_INT) != 0;
- return HICN_LIB_ERROR_NONE;
+ hicn_packet_format_t format = hicn_packet_get_format (pkbuf);
+
+ memset (new, 0, sizeof (_new_header_t));
+ _set_new_header_version (new);
+ uint8_t ah_flag =
+ format.as_u8[pos + 1] == IPPROTO_AH ? HICN_NEW_FLAG_SIG : 0;
+ new->flags |= ah_flag;
+
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-new_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h)
+new_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type)
{
- h->newhdr.flags |= HICN_NEW_FLAG_INT;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ /* Interest packets have the INT bit set */
+ if (new->flags & HICN_NEW_FLAG_INT)
+ *type = HICN_PACKET_TYPE_INTEREST;
+ else
+ *type = HICN_PACKET_TYPE_DATA;
return HICN_LIB_ERROR_NONE;
}
int
-new_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h)
+new_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type)
{
- h->newhdr.flags &= ~HICN_NEW_FLAG_INT;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ switch (type)
+ {
+ case HICN_PACKET_TYPE_INTEREST:
+ new->flags |= HICN_NEW_FLAG_INT;
+ break;
+ case HICN_PACKET_TYPE_DATA:
+ new->flags &= ~HICN_NEW_FLAG_INT;
+ break;
+ default:
+ return -1;
+ }
return HICN_LIB_ERROR_NONE;
}
int
-new_get_interest_locator (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address)
+new_get_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_ip_address_t *ip_address)
{
- assert (is_interest (h->newhdr.flags));
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_interest_locator (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address)
+new_set_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address)
{
- assert (is_interest (h->newhdr.flags));
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
return HICN_LIB_ERROR_NONE;
}
int
-new_get_interest_name (hicn_type_t type, const hicn_protocol_t *h,
+new_get_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_t *name)
{
- assert (is_interest (h->newhdr.flags));
- name->prefix = h->newhdr.prefix;
- name->suffix = ntohl (h->newhdr.suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
+ name->prefix = new->prefix;
+ name->suffix = ntohl (new->suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_interest_name (hicn_type_t type, hicn_protocol_t *h,
+new_set_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_t *name)
{
- int rc = new_mark_packet_as_interest (type, h);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ int rc = new_set_type (pkbuf, pos, HICN_PACKET_TYPE_INTEREST);
if (rc)
return rc;
- assert (is_interest (h->newhdr.flags));
- h->newhdr.prefix = name->prefix;
- h->newhdr.suffix = htonl (name->suffix);
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
+ new->prefix = name->prefix;
+ new->suffix = htonl (name->suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+new_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- assert (is_interest (h->newhdr.flags));
- *suffix = ntohl (h->newhdr.suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
+ *suffix = ntohl (new->suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+new_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- assert (is_interest (h->newhdr.flags));
- h->newhdr.suffix = htonl (*suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
+ new->suffix = htonl (*suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
+new_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- assert (is_interest (h->newhdr.flags));
- return CHILD_OPS (init_packet_header, type, h);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-new_get_data_locator (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address)
+new_get_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_ip_address_t *ip_address)
{
- assert (!is_interest (h->newhdr.flags));
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
+
return HICN_LIB_ERROR_NONE;
}
int
-new_set_data_locator (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address)
+new_set_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *ip_address)
{
- assert (!is_interest (h->newhdr.flags));
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
return HICN_LIB_ERROR_NONE;
}
int
-new_get_data_name (hicn_type_t type, const hicn_protocol_t *h,
+new_get_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_t *name)
{
- assert (!is_interest (h->newhdr.flags));
- name->prefix = h->newhdr.prefix;
- name->suffix = ntohl (h->newhdr.suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ name->prefix = new->prefix;
+ name->suffix = ntohl (new->suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_data_name (hicn_type_t type, hicn_protocol_t *h,
+new_set_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_t *name)
{
- new_mark_packet_as_data (type, h);
- assert (!is_interest (h->newhdr.flags));
- h->newhdr.prefix = name->prefix;
- h->newhdr.suffix = htonl (name->suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ int rc = new_set_type (pkbuf, pos, HICN_PACKET_TYPE_DATA);
+ if (rc)
+ return rc;
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ new->prefix = name->prefix;
+ new->suffix = htonl (name->suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+new_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- assert (!is_interest (h->newhdr.flags));
- *suffix = ntohl (h->newhdr.suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ *suffix = ntohl (new->suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+new_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- assert (!is_interest (h->newhdr.flags));
- h->newhdr.suffix = htonl (*suffix);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ new->suffix = htonl (*suffix);
return HICN_LIB_ERROR_NONE;
}
int
-new_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h,
- u32 *pathlabel)
+new_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t *path_label)
{
- assert (!is_interest (h->newhdr.flags));
- *pathlabel = h->newhdr.path_label;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ *path_label = ntohl (new->path_label);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const u32 pathlabel)
+new_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t path_label)
{
- assert (!is_interest (h->newhdr.flags));
- h->newhdr.path_label = pathlabel;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ new->path_label = htonl (path_label);
return HICN_LIB_ERROR_NONE;
}
int
-new_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const hicn_faceid_t face_id)
+new_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_faceid_t face_id)
{
- hicn_pathlabel_t new_pl;
- update_pathlabel (h->newhdr.path_label, face_id, &new_pl);
- h->newhdr.path_label = new_pl;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_path_label_t new_pl;
+ update_path_label (new->path_label, face_id, &new_pl);
+ new->path_label = new_pl;
return HICN_LIB_ERROR_NONE;
}
int
-new_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+new_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- return CHILD_OPS (reset_data_for_hash, type, h);
+ return CALL_CHILD (reset_data_for_hash, pkbuf, pos);
}
int
-new_get_lifetime (hicn_type_t type, const hicn_protocol_t *h,
+new_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_lifetime_t *lifetime)
{
- *lifetime = ntohl (h->newhdr.lifetime);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ *lifetime = ntohl (new->lifetime);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_lifetime (hicn_type_t type, hicn_protocol_t *h,
+new_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_lifetime_t lifetime)
{
- h->newhdr.lifetime = htonl (lifetime);
- return HICN_LIB_ERROR_NONE;
-}
+ _new_header_t *new = pkbuf_get_new (pkbuf);
-int
-new_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
-{
+ new->lifetime = htonl (lifetime);
return HICN_LIB_ERROR_NONE;
}
int
-new_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+new_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
return HICN_LIB_ERROR_NONE;
}
int
-new_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+new_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first)
{
- assert (is_interest (h->newhdr.flags));
return HICN_LIB_ERROR_NONE;
}
int
-new_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+new_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- assert (!is_interest (h->newhdr.flags));
return HICN_LIB_ERROR_NONE;
}
int
-new_get_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+new_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
- *header_length = NEW_HDRLEN + ntohs (h->newhdr.payload_length);
- return HICN_LIB_ERROR_NONE;
-}
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
-int
-new_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
-{
- *header_length = NEW_HDRLEN;
- return HICN_LIB_ERROR_NONE;
-}
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_INTEREST);
-int
-new_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
-{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *header_length = NEW_HDRLEN + child_header_length;
return HICN_LIB_ERROR_NONE;
}
int
-new_get_payload_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *payload_length)
+new_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *payload_length = ntohs (h->newhdr.payload_length) - child_header_length;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+ _unused (new);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
return HICN_LIB_ERROR_NONE;
}
int
-new_set_payload_length (hicn_type_t type, hicn_protocol_t *h,
- size_t payload_length)
+new_set_payload_len (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t payload_len)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- h->newhdr.payload_length =
- htons ((u_short) (payload_length + child_header_length));
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ /*
+ * The value we have to store in the header is the sum of headers following
+ * the current header + the new payload size
+ */
+
+ size_t child_header_len =
+ (pkbuf->payload - pkbuf->newhdr) - sizeof (_new_header_t);
+ new->payload_len = htons ((u16) child_header_len + payload_len);
return HICN_LIB_ERROR_NONE;
}
int
-new_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
+new_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *signature_size)
{
- return CHILD_OPS (get_signature_size, type, h, signature_size);
+ return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size);
}
int
-new_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
+new_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t signature_size)
{
- return CHILD_OPS (set_signature_size, type, h, signature_size);
+ return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size);
}
int
-new_set_signature_padding (hicn_type_t type, hicn_protocol_t *h,
+new_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t padding)
{
- return CHILD_OPS (set_signature_padding, type, h, padding);
+ return CALL_CHILD (set_signature_padding, pkbuf, pos, padding);
}
int
-new_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
+new_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *padding)
{
- return CHILD_OPS (get_signature_padding, type, h, padding);
+ return CALL_CHILD (get_signature_padding, pkbuf, pos, padding);
}
int
-new_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
+new_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t signature_timestamp)
{
- return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-new_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
+new_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t *signature_timestamp)
{
- return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-new_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
+new_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t validation_algorithm)
{
- return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (set_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-new_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
+new_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t *validation_algorithm)
{
- return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (get_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-new_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+new_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id,
+ size_t key_len)
{
- return CHILD_OPS (set_key_id, type, h, key_id);
+ return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len);
}
int
-new_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size)
+new_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size)
{
- return CHILD_OPS (get_key_id, type, h, key_id, key_id_size);
+ return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size);
}
int
-new_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature)
+new_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **signature)
{
- return CHILD_OPS (get_signature, type, h, signature);
+ return CALL_CHILD (get_signature, pkbuf, pos, signature);
}
int
-new_get_payload_type (hicn_type_t type, const hicn_protocol_t *h,
+new_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag)
+{
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ return new->flags &HICN_NEW_FLAG_SIG;
+}
+
+int
+new_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_payload_type_t *payload_type)
{
- *payload_type = ((h->newhdr.flags & HICN_NEW_FLAG_MAN) == HICN_NEW_FLAG_MAN);
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ *payload_type = ((new->flags &HICN_NEW_FLAG_MAN) == HICN_NEW_FLAG_MAN);
return HICN_LIB_ERROR_NONE;
}
int
-new_set_payload_type (hicn_type_t type, hicn_protocol_t *h,
+new_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_payload_type_t payload_type)
{
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
if (payload_type != HPT_DATA && payload_type != HPT_MANIFEST)
return HICN_LIB_ERROR_INVALID_PARAMETER;
if (payload_type)
- h->newhdr.flags |= HICN_NEW_FLAG_MAN;
+ new->flags |= HICN_NEW_FLAG_MAN;
else
- h->newhdr.flags &= ~HICN_NEW_FLAG_MAN;
+ new->flags &= ~HICN_NEW_FLAG_MAN;
return HICN_LIB_ERROR_NONE;
}
int
-new_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last)
+new_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last)
{
- assert (!is_interest (h->newhdr.flags));
- *is_last = h->newhdr.flags & HICN_NEW_FLAG_LST;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ *is_last = new->flags &HICN_NEW_FLAG_LST;
return HICN_LIB_ERROR_NONE;
}
int
-new_set_last_data (hicn_type_t type, hicn_protocol_t *h)
+new_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos)
{
- assert (!is_interest (h->newhdr.flags));
- h->newhdr.flags |= HICN_NEW_FLAG_LST;
+ _new_header_t *new = pkbuf_get_new (pkbuf);
+
+ hicn_packet_type_t type;
+ _ASSERT (new_get_type (pkbuf, pos, &type) == 0);
+ _ASSERT (type == HICN_PACKET_TYPE_DATA);
+
+ new->flags |= HICN_NEW_FLAG_LST;
return HICN_LIB_ERROR_NONE;
}
-DECLARE_HICN_OPS (new);
+DECLARE_HICN_OPS (new, NEW_HDRLEN);
#pragma GCC diagnostic pop
diff --git a/lib/src/protocol/new.h b/lib/src/protocol/new.h
new file mode 100644
index 000000000..7679910f4
--- /dev/null
+++ b/lib/src/protocol/new.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+/**
+ * @file protocol/ah.h
+ * @brief AH packet header
+ */
+#ifndef HICN_PROTOCOL_NEW_H
+#define HICN_PROTOCOL_NEW_H
+
+#include <hicn/common.h>
+#include <hicn/name.h>
+
+/*
+ * The length of the new header struct must be 28 bytes.
+ */
+#define EXPECTED_NEW_HDRLEN 32
+
+typedef struct
+{
+ u8 version_reserved;
+ u8 flags;
+
+ /* Size of the payload direcly after the new header */
+ u16 payload_len;
+
+ u32 lifetime;
+
+ /* Name prefix and suffix */
+ hicn_ip_address_t prefix;
+ u32 suffix;
+
+ /* We reserve 32 bits for the path label */
+ u32 path_label;
+} _new_header_t;
+
+#define NEW_HDRLEN sizeof (_new_header_t)
+static_assert (EXPECTED_NEW_HDRLEN == NEW_HDRLEN,
+ "Size of new_header Struct does not match its expected size.");
+
+/* TCP flags bit 0 first. */
+#define foreach_hicn_new_flag \
+ _ (SIG) /**< Signature header after. */ \
+ _ (MAN) /**< Payload type is manifest. */ \
+ _ (INT) /**< Packet is interest. */ \
+ _ (LST) /**< Last data. */
+
+enum
+{
+#define _(f) HICN_NEW_FLAG_BIT_##f,
+ foreach_hicn_new_flag
+#undef _
+ HICN_NEW_N_FLAG_BITS,
+};
+
+enum
+{
+#define _(f) HICN_NEW_FLAG_##f = 1 << HICN_NEW_FLAG_BIT_##f,
+ foreach_hicn_new_flag
+#undef _
+};
+
+static inline int
+_get_new_header_version (const _new_header_t *new_hdr)
+{
+ return ((new_hdr->version_reserved >> 4) & 0x0F);
+}
+
+static inline void
+_set_new_header_version (_new_header_t *new_hdr)
+{
+ new_hdr->version_reserved = (0x9 << 4) & 0xF0;
+}
+
+#endif /* HICN_PROTOCOL_NEW_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/tcp.c b/lib/src/protocol/tcp.c
index 82fc461ea..822bd3e0c 100644
--- a/lib/src/protocol/tcp.c
+++ b/lib/src/protocol/tcp.c
@@ -14,9 +14,12 @@
*/
#include <string.h>
-#include <hicn/protocol/tcp.h>
+
+#include <hicn/base.h>
#include <hicn/error.h>
-#include <hicn/ops.h>
+
+#include "tcp.h"
+#include "../ops.h"
#define TCP_DEFAULT_SRC_PORT 0x8000
#define TCP_DEFAULT_DST_PORT 0x0080
@@ -32,6 +35,8 @@
#define TCP_DEFAULT_SYN 1
#define TCP_DEFAULT_FIN 0
+#define UINT16_T_MASK 0x0000ffff // 1111 1111 1111 1111
+
DECLARE_get_interest_locator (tcp, UNEXPECTED);
DECLARE_set_interest_locator (tcp, UNEXPECTED);
DECLARE_get_interest_name (tcp, UNEXPECTED);
@@ -40,21 +45,26 @@ DECLARE_get_data_locator (tcp, UNEXPECTED);
DECLARE_set_data_locator (tcp, UNEXPECTED);
DECLARE_get_data_name (tcp, UNEXPECTED);
DECLARE_set_data_name (tcp, UNEXPECTED);
-DECLARE_get_length (tcp, UNEXPECTED);
-DECLARE_get_payload_length (tcp, UNEXPECTED);
-DECLARE_set_payload_length (tcp, UNEXPECTED);
+DECLARE_set_payload_len (tcp, UNEXPECTED);
+DECLARE_get_ttl (tcp, UNEXPECTED);
+DECLARE_set_ttl (tcp, UNEXPECTED);
+
+int tcp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first);
static inline void
-reset_for_hash (hicn_protocol_t *h)
+reset_for_hash (hicn_packet_buffer_t *pkbuf)
{
- h->tcp.sport = 0;
- h->tcp.dport = 0;
- h->tcp.seq_ack = 0;
- h->tcp.data_offset_and_reserved = 0;
- h->tcp.flags = 0;
- h->tcp.window = 0;
- h->tcp.csum = 0;
- h->tcp.urg_ptr = 0;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ tcp->sport = 0;
+ tcp->dport = 0;
+ tcp->seq_ack = 0;
+ tcp->data_offset_and_reserved = 0;
+ tcp->flags = 0;
+ tcp->window = 0;
+ tcp->csum = 0;
+ tcp->urg_ptr = 0;
}
static inline int
@@ -80,9 +90,17 @@ check_tcp_checksum (u16 csum)
}
int
-tcp_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+tcp_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- h->tcp = (_tcp_header_t){
+ pkbuf->tcp = pkbuf->len;
+ if (TCP_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += TCP_HDRLEN;
+
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ hicn_packet_format_t format = hicn_packet_get_format (pkbuf);
+
+ *tcp = (_tcp_header_t){
.sport = htons (TCP_DEFAULT_SRC_PORT),
.dport = htons (TCP_DEFAULT_DST_PORT),
.seq = 0,
@@ -97,142 +115,169 @@ tcp_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
.urg_ptr = 65000,
};
- uint8_t ah_flag = type.l2 == IPPROTO_AH ? AH_FLAG : 0;
+ uint8_t ah_flag = ((format.as_u8[pos + 1] == IPPROTO_AH) ? AH_FLAG : 0);
- h->tcp.flags |= ah_flag;
+ tcp->flags |= ah_flag;
- return CHILD_OPS (init_packet_header, type, h);
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-tcp_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest)
+tcp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type)
{
- *is_interest = (h->tcp.flags & HICN_TCP_FLAG_ECE) == 0;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ /* Data packets have the ECE bit set */
+ if (tcp->flags & HICN_TCP_FLAG_ECE)
+ *type = HICN_PACKET_TYPE_DATA;
+ else
+ *type = HICN_PACKET_TYPE_INTEREST;
return HICN_LIB_ERROR_NONE;
}
int
-tcp_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h)
+tcp_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type)
{
- h->tcp.flags &= ~HICN_TCP_FLAG_ECE;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ switch (type)
+ {
+ case HICN_PACKET_TYPE_INTEREST:
+ tcp->flags &= ~HICN_TCP_FLAG_ECE;
+ break;
+ case HICN_PACKET_TYPE_DATA:
+ tcp->flags |= HICN_TCP_FLAG_ECE;
+ break;
+ default:
+ return HICN_LIB_ERROR_INVALID_PARAMETER;
+ }
return HICN_LIB_ERROR_NONE;
}
int
-tcp_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- *suffix = ntohl (h->tcp.name_suffix);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *suffix = ntohl (tcp->name_suffix);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- int rc = tcp_mark_packet_as_interest (type, h);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ int rc = tcp_set_type (pkbuf, pos, HICN_PACKET_TYPE_INTEREST);
if (rc)
return rc;
- h->tcp.name_suffix = htonl (*suffix);
+ tcp->name_suffix = htonl (*suffix);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h)
+tcp_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- h->tcp.flags |= HICN_TCP_FLAG_ECE;
- return HICN_LIB_ERROR_NONE;
+ reset_for_hash (pkbuf);
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-tcp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
-{
- reset_for_hash (h);
- return CHILD_OPS (reset_interest_for_hash, type, h);
-}
-
-int
-tcp_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- *suffix = ntohl (h->tcp.name_suffix);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *suffix = ntohl (tcp->name_suffix);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- int rc = tcp_mark_packet_as_data (type, h);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ int rc = tcp_set_type (pkbuf, pos, HICN_PACKET_TYPE_DATA);
if (rc)
return rc;
- h->tcp.name_suffix = htonl (*suffix);
+ tcp->name_suffix = htonl (*suffix);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h,
- u32 *pathlabel)
+tcp_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t *path_label)
{
- *pathlabel = h->tcp.seq_ack;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *path_label =
+ (hicn_path_label_t) (tcp->seq_ack >> (32 - HICN_PATH_LABEL_SIZE_BITS));
return HICN_LIB_ERROR_NONE;
}
int
-tcp_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const u32 pathlabel)
+tcp_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t path_label)
{
- h->tcp.seq_ack = pathlabel;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ hicn_path_label_t old_path_label;
+ tcp_get_data_path_label (pkbuf, pos, &old_path_label);
+
+ tcp->seq_ack = (path_label << (32 - HICN_PATH_LABEL_SIZE_BITS));
+
+ tcp_update_checksums_incremental (
+ pkbuf, pos, (uint16_t *) &old_path_label, (uint16_t *) &path_label,
+ sizeof (hicn_path_label_t) / sizeof (uint16_t), true);
+
return HICN_LIB_ERROR_NONE;
}
int
-tcp_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const hicn_faceid_t face_id)
+tcp_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_faceid_t face_id)
{
- hicn_pathlabel_t pl =
- (hicn_pathlabel_t) (h->tcp.seq_ack >> (32 - HICN_PATH_LABEL_SIZE));
+ assert (sizeof (hicn_path_label_t) == 1);
- hicn_pathlabel_t new_pl;
+ hicn_path_label_t old_path_label;
+ hicn_path_label_t new_path_label;
- update_pathlabel (pl, face_id, &new_pl);
- h->tcp.seq_ack = (new_pl << (32 - HICN_PATH_LABEL_SIZE));
+ tcp_get_data_path_label (pkbuf, pos, &old_path_label);
+ update_path_label (old_path_label, face_id, &new_path_label);
+ tcp_set_data_path_label (pkbuf, pos, new_path_label);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+tcp_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- reset_for_hash (h);
- return CHILD_OPS (reset_data_for_hash, type, h);
+ reset_for_hash (pkbuf);
+ return CALL_CHILD (reset_data_for_hash, pkbuf, pos);
}
int
-tcp_get_lifetime (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_lifetime_t *lifetime)
{
- *lifetime = ntohs (h->tcp.urg_ptr)
- << (h->tcp.data_offset_and_reserved & 0xF);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *lifetime = ntohs (tcp->urg_ptr) << (tcp->data_offset_and_reserved & 0xF);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_set_lifetime (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_lifetime_t lifetime)
{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
u8 multiplier = 0;
u32 lifetime_scaled = lifetime;
- if (PREDICT_FALSE (lifetime >= HICN_MAX_LIFETIME))
+ if (HICN_EXPECT_FALSE (lifetime >= HICN_MAX_LIFETIME))
{
- h->tcp.urg_ptr = htons (HICN_MAX_LIFETIME_SCALED);
- h->tcp.data_offset_and_reserved =
- (h->tcp.data_offset_and_reserved & ~0x0F) |
- HICN_MAX_LIFETIME_MULTIPLIER;
+ tcp->urg_ptr = htons (HICN_MAX_LIFETIME_SCALED);
+ tcp->data_offset_and_reserved =
+ (tcp->data_offset_and_reserved & ~0x0F) | HICN_MAX_LIFETIME_MULTIPLIER;
return HICN_LIB_ERROR_NONE;
}
@@ -243,70 +288,76 @@ tcp_set_lifetime (hicn_type_t type, hicn_protocol_t *h,
lifetime_scaled = lifetime_scaled >> 1;
}
- h->tcp.urg_ptr = htons (lifetime_scaled);
- h->tcp.data_offset_and_reserved =
- (h->tcp.data_offset_and_reserved & ~0x0F) | multiplier;
+ tcp->urg_ptr = htons (lifetime_scaled);
+ tcp->data_offset_and_reserved =
+ (tcp->data_offset_and_reserved & ~0x0F) | multiplier;
return HICN_LIB_ERROR_NONE;
}
int
-tcp_get_source_port (hicn_type_t type, const hicn_protocol_t *h,
- u16 *source_port)
+tcp_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- *source_port = ntohs (h->tcp.sport);
- return HICN_LIB_ERROR_NONE;
-}
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ /* TODO bound checks for payload_len based on pkbuf size */
+ assert (payload_len != ~0);
-int
-tcp_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port)
-{
- *dest_port = ntohs (h->tcp.dport);
- return HICN_LIB_ERROR_NONE;
-}
+ tcp->csum = 0;
-int
-tcp_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port)
-{
- h->tcp.sport = htons (source_port);
- return HICN_LIB_ERROR_NONE;
-}
+ if (HICN_EXPECT_TRUE (partial_csum != 0))
+ {
+ partial_csum = ~partial_csum;
+ }
-int
-tcp_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port)
-{
- h->tcp.dport = htons (dest_port);
- return HICN_LIB_ERROR_NONE;
+ tcp->csum =
+ csum (pkbuf_get_header (pkbuf), TCP_HDRLEN + payload_len, partial_csum);
+
+ return CALL_CHILD (update_checksums, pkbuf, pos, 0, payload_len);
}
int
-tcp_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+tcp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first)
{
- h->tcp.csum = 0;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ if (skip_first)
+ return HICN_LIB_ERROR_INVALID_PARAMETER;
- if (PREDICT_TRUE (partial_csum != 0))
+ for (uint8_t i = 0; i < size; i++)
{
- partial_csum = ~partial_csum;
+ uint16_t old_csum = ~tcp->csum;
+ uint16_t not_old_val = ~(*old_val);
+ uint32_t sum = (uint32_t) old_csum + not_old_val + *new_val;
+
+ while (sum >> 16)
+ {
+ sum = (sum >> 16) + (sum & UINT16_T_MASK);
+ }
+
+ tcp->csum = ~sum;
+ ++old_val;
+ ++new_val;
}
- h->tcp.csum = csum (h, TCP_HDRLEN + payload_length, partial_csum);
-
- return CHILD_OPS (update_checksums, type, h, 0, payload_length);
+ return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val,
+ new_val, size, false);
}
int
-tcp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+tcp_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- if (PREDICT_TRUE (partial_csum != 0))
+ if (HICN_EXPECT_TRUE (partial_csum != 0))
{
partial_csum = ~partial_csum;
}
- if (csum (h, TCP_HDRLEN + payload_length, partial_csum) != 0)
+ if (csum (pkbuf_get_header (pkbuf), TCP_HDRLEN + payload_len,
+ partial_csum) != 0)
return HICN_LIB_ERROR_CORRUPTED_PACKET;
- return CHILD_OPS (verify_checksums, type, h, 0, payload_length);
+ return CALL_CHILD (verify_checksums, pkbuf, pos, 0, payload_len);
}
#define TCP_OFFSET_MASK 13
@@ -331,10 +382,14 @@ tcp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
#define TCP_DEFAULT_FIN 0
int
-tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+tcp_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
- u16 *tcp_checksum = &(h->tcp.csum);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ _ipv6_header_t *ip6 = pkbuf_get_ipv6 (pkbuf);
+
+ u16 *tcp_checksum = &(tcp->csum);
int ret = check_tcp_checksum (*tcp_checksum);
if (ret)
@@ -347,14 +402,14 @@ tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
* whole struct by interpreting it as IPv6 in all cases
*
* v4 code would be:
- * csum = ip_csum_sub_even (*tcp_checksum, h->ipv4.saddr.as_u32);
- * csum = ip_csum_add_even (csum, h->ipv4.saddr.as_u32);
+ * csum = ip_csum_sub_even (*tcp_checksum, h->tcp.saddr.as_u32);
+ * csum = ip_csum_add_even (csum, h->tcp.saddr.as_u32);
*/
- ip_csum_t csum =
- ip_csum_sub_even (*tcp_checksum, (ip_csum_t) (h->ipv6.saddr.as_u64[0]));
- csum = ip_csum_sub_even (csum, (ip_csum_t) (h->ipv6.saddr.as_u64[1]));
- csum = ip_csum_add_even (csum, (ip_csum_t) (h->ipv6.saddr.as_u64[0]));
- csum = ip_csum_add_even (csum, (ip_csum_t) (h->ipv6.saddr.as_u64[1]));
+ hicn_ip_csum_t csum =
+ ip_csum_sub_even (*tcp_checksum, (hicn_ip_csum_t) (ip6->saddr.as_u64[0]));
+ csum = ip_csum_sub_even (csum, (hicn_ip_csum_t) (ip6->saddr.as_u64[1]));
+ csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (ip6->saddr.as_u64[0]));
+ csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (ip6->saddr.as_u64[1]));
*tcp_checksum = ip_csum_fold (csum);
@@ -362,21 +417,22 @@ tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
}
int
-tcp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+tcp_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
-
- u16 *tcp_checksum = &(h->tcp.csum);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ u16 *tcp_checksum = &(tcp->csum);
int ret = check_tcp_checksum (*tcp_checksum);
/*
* update path label
*/
- u16 old_pl = h->tcp.seq_ack;
+ u16 old_pl = tcp->seq_ack;
if (reset_pl)
- h->tcp.seq_ack = 0;
- tcp_update_data_pathlabel (type, h, face_id);
+ tcp->seq_ack = 0;
+ tcp_update_data_path_label (pkbuf, pos, face_id);
if (ret)
{
@@ -388,18 +444,18 @@ tcp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
* whole struct by interpreting it as IPv6 in all cases
*
* v4 code would be:
- * csum = ip_csum_sub_even (*tcp_checksum, h->ipv4.saddr.as_u32);
- * csum = ip_csum_add_even (csum, h->ipv4.saddr.as_u32);
+ * csum = ip_csum_sub_even (*tcp_checksum, h->tcp.saddr.as_u32);
+ * csum = ip_csum_add_even (csum, h->tcp.saddr.as_u32);
*/
- ip_csum_t csum =
- ip_csum_sub_even (*tcp_checksum, (ip_csum_t) (addr_old->v6.as_u64[0]));
- csum =
- ip_csum_sub_even (*tcp_checksum, (ip_csum_t) (addr_old->v6.as_u64[1]));
- csum = ip_csum_add_even (csum, (ip_csum_t) (addr_new->v6.as_u64[0]));
- csum = ip_csum_add_even (csum, (ip_csum_t) (addr_new->v6.as_u64[1]));
+ hicn_ip_csum_t csum = ip_csum_sub_even (
+ *tcp_checksum, (hicn_ip_csum_t) (addr_old->v6.as_u64[0]));
+ csum = ip_csum_sub_even (*tcp_checksum,
+ (hicn_ip_csum_t) (addr_old->v6.as_u64[1]));
+ csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (addr_new->v6.as_u64[0]));
+ csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (addr_new->v6.as_u64[1]));
csum = ip_csum_sub_even (csum, old_pl);
- csum = ip_csum_add_even (csum, h->tcp.seq_ack);
+ csum = ip_csum_add_even (csum, tcp->seq_ack);
*tcp_checksum = ip_csum_fold (csum);
@@ -407,139 +463,166 @@ tcp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
}
int
-tcp_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
-{
- *header_length = TCP_HDRLEN;
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-tcp_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
-{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
-
- *header_length = TCP_HDRLEN + child_header_length;
- return HICN_LIB_ERROR_NONE;
-}
-
-int
-tcp_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *signature_size)
{
- return CHILD_OPS (get_signature_size, type, h, signature_size);
+ return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size);
}
int
-tcp_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t signature_size)
{
- return CHILD_OPS (set_signature_size, type, h, signature_size);
+ return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size);
}
int
-tcp_set_signature_padding (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t padding)
{
- return CHILD_OPS (set_signature_padding, type, h, padding);
+ return CALL_CHILD (set_signature_padding, pkbuf, pos, padding);
}
int
-tcp_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
size_t *padding)
{
- return CHILD_OPS (get_signature_padding, type, h, padding);
+ return CALL_CHILD (get_signature_padding, pkbuf, pos, padding);
}
int
-tcp_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t signature_timestamp)
{
- return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-tcp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint64_t *signature_timestamp)
{
- return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-tcp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t validation_algorithm)
{
- return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (set_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-tcp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
+tcp_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
uint8_t *validation_algorithm)
{
- return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (get_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-tcp_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+tcp_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id,
+ size_t key_len)
{
- return CHILD_OPS (set_key_id, type, h, key_id);
+ return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len);
}
int
-tcp_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size)
+tcp_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size)
{
- return CHILD_OPS (get_key_id, type, h, key_id, key_id_size);
+ return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size);
}
int
-tcp_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature)
+tcp_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **signature)
{
- return CHILD_OPS (get_signature, type, h, signature);
+ return CALL_CHILD (get_signature, pkbuf, pos, signature);
}
int
-tcp_get_payload_type (hicn_type_t type, const hicn_protocol_t *h,
+tcp_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag)
+{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *flag = tcp->flags & AH_FLAG;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_payload_type_t *payload_type)
{
- *payload_type = ((h->tcp.flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG);
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *payload_type = ((tcp->flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_set_payload_type (hicn_type_t type, hicn_protocol_t *h,
+tcp_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_payload_type_t payload_type)
{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
if (payload_type != HPT_DATA && payload_type != HPT_MANIFEST)
return HICN_LIB_ERROR_INVALID_PARAMETER;
if (payload_type)
- h->tcp.flags |= HICN_TCP_FLAG_URG;
+ tcp->flags |= HICN_TCP_FLAG_URG;
else
- h->tcp.flags &= ~HICN_TCP_FLAG_URG;
+ tcp->flags &= ~HICN_TCP_FLAG_URG;
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last)
+{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *is_last = (tcp->flags & HICN_TCP_FLAG_RST) == HICN_TCP_FLAG_RST;
+ return HICN_LIB_ERROR_NONE;
+}
+int
+tcp_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos)
+{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ tcp->flags |= HICN_TCP_FLAG_RST;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
+{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *port = ntohs (tcp->sport);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
+{
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ tcp->sport = htons (port);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last)
+tcp_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- *is_last = (h->tcp.flags & HICN_TCP_FLAG_RST) == HICN_TCP_FLAG_RST;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ *port = ntohs (tcp->dport);
return HICN_LIB_ERROR_NONE;
}
int
-tcp_set_last_data (hicn_type_t type, hicn_protocol_t *h)
+tcp_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- h->tcp.flags |= HICN_TCP_FLAG_RST;
+ _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf);
+ tcp->dport = htons (port);
return HICN_LIB_ERROR_NONE;
}
-DECLARE_HICN_OPS (tcp);
+DECLARE_HICN_OPS (tcp, TCP_HDRLEN);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/lib/src/protocol/tcp.h b/lib/src/protocol/tcp.h
new file mode 100644
index 000000000..e563372d0
--- /dev/null
+++ b/lib/src/protocol/tcp.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+#ifndef HICN_PROTOCOL_TCP_H
+#define HICN_PROTOCOL_TCP_H
+
+#include <hicn/base.h>
+#include <hicn/common.h>
+#include <hicn/name.h>
+
+/*
+ * The length of the TCP header struct must be 20 bytes.
+ */
+#define EXPECTED_TCP_HDRLEN 20
+
+/*
+ * NOTE: bitfields are problematic for portability reasons. There are provided
+ * here for reference and documentation purposes, we might just provide a macro
+ * to disable and use it instead of __BYTE_ORDER__.
+ */
+typedef struct
+{
+ u16 sport;
+ u16 dport;
+ union
+ {
+ u32 seq;
+ hicn_name_suffix_t name_suffix;
+ };
+ union
+ {
+ u32 seq_ack;
+ struct
+ {
+ hicn_path_label_t pathlabel;
+ u8 pad[3];
+ };
+ };
+
+ union
+ {
+ struct
+ {
+ u8 data_offset_and_reserved;
+ u8 flags;
+ };
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ struct
+ {
+ u16 reserved : 4;
+ u16 doff : 4;
+ u16 fin : 1;
+ u16 syn : 1;
+ u16 rst : 1;
+ u16 psh : 1;
+ u16 ack : 1;
+ u16 urg : 1;
+ u16 ece : 1;
+ u16 cwr : 1;
+ };
+ struct
+ { /* __ denotes unchanged bitfields */
+ u16 timescale : 4;
+ u16 __doff : 4;
+ u16 __fin : 1;
+ u16 __syn : 1;
+ u16 __rst : 1;
+ u16 sig : 1;
+ u16 __ack : 1;
+ u16 man : 1;
+ u16 id : 1;
+ u16 __cwr : 1;
+ };
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ struct
+ {
+ u16 doff : 4;
+ u16 reserved : 4;
+ u16 cwr : 1;
+ u16 ece : 1;
+ u16 urg : 1;
+ u16 ack : 1;
+ u16 psh : 1;
+ u16 rst : 1;
+ u16 syn : 1;
+ u16 fin : 1;
+ };
+ struct
+ {
+ u16 __doff : 4;
+ u16 timescale : 4;
+ u16 __cwr : 1;
+ u16 id : 1 u16 man : 1;
+ u16 __ack : 1;
+ u16 sig : 1;
+ u16 __rst : 1;
+ u16 __syn : 1;
+ u16 __fin : 1;
+ };
+#endif
+ };
+ union
+ {
+ u16 window;
+ u16 ldr;
+ };
+ u16 csum;
+ union
+ {
+ u16 urg_ptr;
+ u16 lifetime;
+ };
+} _tcp_header_t;
+
+#define TCP_HDRLEN sizeof (_tcp_header_t)
+static_assert (EXPECTED_TCP_HDRLEN == TCP_HDRLEN,
+ "Size of TCP struct does not match its expected size.");
+
+/* TCP flags bit 0 first. */
+#define foreach_tcp_flag \
+ _ (FIN) /**< No more data from sender. */ \
+ _ (SYN) /**< Synchronize sequence numbers. */ \
+ _ (RST) /**< Reset the connection. */ \
+ _ (PSH) /**< Push function. */ \
+ _ (ACK) /**< Ack field significant. */ \
+ _ (URG) /**< Urgent pointer field significant. */ \
+ _ (ECE) /**< ECN-echo. Receiver got CE packet */ \
+ _ (CWR) /**< Sender reduced congestion window */
+
+enum
+{
+#define _(f) HICN_TCP_FLAG_BIT_##f,
+ foreach_tcp_flag
+#undef _
+ HICN_TCP_N_FLAG_BITS,
+};
+
+enum
+{
+#define _(f) HICN_TCP_FLAG_##f = 1 << HICN_TCP_FLAG_BIT_##f,
+ foreach_tcp_flag
+#undef _
+};
+
+#endif /* HICN_PROTOCOL_TCP_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/udp.c b/lib/src/protocol/udp.c
index 7a14b09c2..ff2355b0c 100644
--- a/lib/src/protocol/udp.c
+++ b/lib/src/protocol/udp.c
@@ -17,9 +17,9 @@
#include <string.h>
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/ops.h>
-#include <hicn/protocol/udp.h>
+#include "udp.h"
+#include "../ops.h"
DECLARE_get_interest_locator (udp, UNEXPECTED);
DECLARE_set_interest_locator (udp, UNEXPECTED);
@@ -29,308 +29,313 @@ DECLARE_get_data_locator (udp, UNEXPECTED);
DECLARE_set_data_locator (udp, UNEXPECTED);
DECLARE_get_data_name (udp, UNEXPECTED);
DECLARE_set_data_name (udp, UNEXPECTED);
-DECLARE_get_payload_length (udp, UNEXPECTED);
-DECLARE_set_payload_length (udp, UNEXPECTED);
+DECLARE_set_payload_len (udp, UNEXPECTED);
+DECLARE_get_ttl (udp, UNEXPECTED);
+DECLARE_set_ttl (udp, UNEXPECTED);
int
-udp_init_packet_header (hicn_type_t type, hicn_protocol_t *h)
+udp_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- size_t total_header_length;
- int rc = CHILD_OPS (get_header_length, type, h, &total_header_length);
- if (rc < 0)
- return rc;
+ pkbuf->udp = pkbuf->len;
+ if (UDP_HDRLEN > pkbuf->buffer_size - pkbuf->len)
+ return -1;
+ pkbuf->len += UDP_HDRLEN;
- /* *INDENT-OFF* */
- h->udp = (_udp_header_t){ .src_port = 0,
- .dst_port = 0,
- .length = htons ((u16) total_header_length),
- .checksum = 0 };
- /* *INDENT-ON* */
- return CHILD_OPS (init_packet_header, type, h);
+ _udp_header_t *udp = pkbuf_get_udp (pkbuf);
+
+ size_t len = hicn_packet_get_len (pkbuf) -
+ ((u8 *) udp - pkbuf_get_header (pkbuf)) -
+ sizeof (_udp_header_t);
+
+ // clang-format off
+ *udp = (_udp_header_t){
+ .src_port = 0,
+ .dst_port = 0,
+ .len = htons ((u16) len),
+ .checksum = 0
+ };
+ // clang-format on
+ return CALL_CHILD (init_packet_header, pkbuf, pos);
}
int
-udp_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+udp_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (get_interest_name_suffix, type, h, suffix);
+ return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, suffix);
}
int
-udp_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+udp_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (set_interest_name_suffix, type, h, suffix);
-}
-
-int
-udp_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest)
-{
- return CHILD_OPS (is_interest, type, h, is_interest);
+ return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, suffix);
}
int
-udp_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h)
+udp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos,
+ hicn_packet_type_t *type)
{
- return CHILD_OPS (mark_packet_as_interest, type, h);
+ return CALL_CHILD (get_type, pkbuf, pos, type);
}
int
-udp_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h)
+udp_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_packet_type_t type)
{
- return CHILD_OPS (mark_packet_as_data, type, h);
+ return CALL_CHILD (set_type, pkbuf, pos, type);
}
int
-udp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h)
+udp_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- return CHILD_OPS (reset_interest_for_hash, type, h);
+ return CALL_CHILD (reset_interest_for_hash, pkbuf, pos);
}
int
-udp_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h,
+udp_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (get_data_name_suffix, type, h, suffix);
+ return CALL_CHILD (get_data_name_suffix, pkbuf, pos, suffix);
}
int
-udp_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h,
+udp_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_name_suffix_t *suffix)
{
- return CHILD_OPS (set_data_name_suffix, type, h, suffix);
+ return CALL_CHILD (set_data_name_suffix, pkbuf, pos, suffix);
}
int
-udp_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h,
- u32 *pathlabel)
+udp_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t *path_label)
{
- return CHILD_OPS (get_data_pathlabel, type, h, pathlabel);
+ return CALL_CHILD (get_data_path_label, pkbuf, pos, path_label);
}
int
-udp_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const u32 pathlabel)
+udp_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_path_label_t path_label)
{
- return CHILD_OPS (set_data_pathlabel, type, h, pathlabel);
+ return CALL_CHILD (set_data_path_label, pkbuf, pos, path_label);
}
int
-udp_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h,
- const hicn_faceid_t face_id)
+udp_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_faceid_t face_id)
{
- return CHILD_OPS (update_data_pathlabel, type, h, face_id);
+ return CALL_CHILD (update_data_path_label, pkbuf, pos, face_id);
}
int
-udp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h)
+udp_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos)
{
- return CHILD_OPS (reset_data_for_hash, type, h);
+ return CALL_CHILD (reset_data_for_hash, pkbuf, pos);
}
int
-udp_get_lifetime (hicn_type_t type, const hicn_protocol_t *h,
+udp_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
hicn_lifetime_t *lifetime)
{
- return CHILD_OPS (get_lifetime, type, h, lifetime);
+ return CALL_CHILD (get_lifetime, pkbuf, pos, lifetime);
}
int
-udp_set_lifetime (hicn_type_t type, hicn_protocol_t *h,
+udp_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos,
const hicn_lifetime_t lifetime)
{
- return CHILD_OPS (set_lifetime, type, h, lifetime);
+ return CALL_CHILD (set_lifetime, pkbuf, pos, lifetime);
}
int
-udp_get_source_port (hicn_type_t type, const hicn_protocol_t *h,
- u16 *source_port)
+udp_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- *source_port = ntohs (h->udp.src_port);
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (update_checksums, pkbuf, pos, partial_csum, payload_len);
}
int
-udp_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port)
+udp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf,
+ size_t pos, u16 *old_val, u16 *new_val,
+ u8 size, bool skip_first)
{
- *dest_port = ntohs (h->udp.dst_port);
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val,
+ new_val, size, false);
}
int
-udp_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port)
+udp_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ u16 partial_csum, size_t payload_len)
{
- h->udp.src_port = htons (source_port);
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (verify_checksums, pkbuf, pos, partial_csum, payload_len);
}
int
-udp_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port)
+udp_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old)
{
- h->udp.dst_port = htons (dest_port);
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (rewrite_interest, pkbuf, pos, addr_new, addr_old);
}
int
-udp_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+udp_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *addr_old, const hicn_faceid_t face_id,
+ u8 reset_pl)
{
- return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length);
+ return CALL_CHILD (rewrite_data, pkbuf, pos, addr_new, addr_old, face_id,
+ reset_pl);
}
int
-udp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum,
- size_t payload_length)
+udp_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t *payload_type)
{
- return CHILD_OPS (verify_checksums, type, h, partial_csum, payload_length);
+ return CALL_CHILD (get_payload_type, pkbuf, pos, payload_type);
}
int
-udp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old)
+udp_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ hicn_payload_type_t payload_type)
{
- return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old);
+ return CALL_CHILD (set_payload_type, pkbuf, pos, payload_type);
}
int
-udp_rewrite_data (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new, ip_address_t *addr_old,
- const hicn_faceid_t face_id, u8 reset_pl)
+udp_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t *signature_size)
{
- return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id,
- reset_pl);
+ return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size);
}
int
-udp_get_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+udp_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t signature_size)
{
- *header_length = IPV6_HDRLEN + ntohs (h->ipv6.len);
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size);
}
int
-udp_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+udp_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag)
{
- *header_length = UDP_HDRLEN;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (has_signature, pkbuf, pos, flag);
}
int
-udp_get_header_length (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length)
+udp_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t padding)
{
- size_t child_header_length = 0;
- int rc = CHILD_OPS (get_header_length, type, h, &child_header_length);
- if (rc < 0)
- return rc;
- *header_length = UDP_HDRLEN + child_header_length;
- return HICN_LIB_ERROR_NONE;
+ return CALL_CHILD (set_signature_padding, pkbuf, pos, padding);
}
int
-udp_get_payload_type (hicn_type_t type, const hicn_protocol_t *h,
- hicn_payload_type_t *payload_type)
+udp_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ size_t *padding)
{
- return CHILD_OPS (get_payload_type, type, h, payload_type);
+ return CALL_CHILD (get_signature_padding, pkbuf, pos, padding);
}
int
-udp_set_payload_type (hicn_type_t type, hicn_protocol_t *h,
- hicn_payload_type_t payload_type)
+udp_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint64_t signature_timestamp)
{
- return CHILD_OPS (set_payload_type, type, h, payload_type);
+ return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-udp_get_signature_size (hicn_type_t type, const hicn_protocol_t *h,
- size_t *signature_size)
+udp_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint64_t *signature_timestamp)
{
- return CHILD_OPS (get_signature_size, type, h, signature_size);
+ return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp);
}
int
-udp_set_signature_size (hicn_type_t type, hicn_protocol_t *h,
- size_t signature_size)
+udp_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t validation_algorithm)
{
- return CHILD_OPS (set_signature_size, type, h, signature_size);
+ return CALL_CHILD (set_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-udp_set_signature_padding (hicn_type_t type, hicn_protocol_t *h,
- size_t padding)
+udp_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t *validation_algorithm)
{
- return CHILD_OPS (set_signature_padding, type, h, padding);
+ return CALL_CHILD (get_validation_algorithm, pkbuf, pos,
+ validation_algorithm);
}
int
-udp_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h,
- size_t *padding)
+udp_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id,
+ size_t key_len)
{
- return CHILD_OPS (get_signature_padding, type, h, padding);
+ return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len);
}
int
-udp_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h,
- uint64_t signature_timestamp)
+udp_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **key_id, uint8_t *key_id_size)
{
- return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size);
}
int
-udp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h,
- uint64_t *signature_timestamp)
+udp_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos,
+ uint8_t **signature)
{
- return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+ return CALL_CHILD (get_signature, pkbuf, pos, signature);
}
int
-udp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h,
- uint8_t validation_algorithm)
+udp_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last)
{
- return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (is_last_data, pkbuf, pos, is_last);
}
int
-udp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h,
- uint8_t *validation_algorithm)
+udp_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos)
{
- return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+ return CALL_CHILD (set_last_data, pkbuf, pos);
}
int
-udp_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id)
+udp_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- return CHILD_OPS (set_key_id, type, h, key_id);
-}
+ _udp_header_t *udp = pkbuf_get_udp (pkbuf);
-int
-udp_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size)
-{
- return CHILD_OPS (get_key_id, type, h, key_id, key_id_size);
+ *port = udp->src_port;
+ return HICN_LIB_ERROR_NONE;
}
int
-udp_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature)
+udp_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- return CHILD_OPS (get_signature, type, h, signature);
+ _udp_header_t *udp = pkbuf_get_udp (pkbuf);
+
+ udp->src_port = port;
+ return HICN_LIB_ERROR_NONE;
}
int
-udp_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last)
+udp_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port)
{
- return CHILD_OPS (is_last_data, type, h, is_last);
+ _udp_header_t *udp = pkbuf_get_udp (pkbuf);
+
+ *port = udp->dst_port;
+ return HICN_LIB_ERROR_NONE;
}
int
-udp_set_last_data (hicn_type_t type, hicn_protocol_t *h)
+udp_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port)
{
- return CHILD_OPS (set_last_data, type, h);
+ _udp_header_t *udp = pkbuf_get_udp (pkbuf);
+
+ udp->dst_port = port;
+ return HICN_LIB_ERROR_NONE;
}
-DECLARE_HICN_OPS (udp);
+DECLARE_HICN_OPS (udp, UDP_HDRLEN);
/*
* fd.io coding-style-patch-verification: ON
diff --git a/lib/src/protocol/udp.h b/lib/src/protocol/udp.h
new file mode 100644
index 000000000..23f5317b3
--- /dev/null
+++ b/lib/src/protocol/udp.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 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.
+ */
+
+#ifndef HICN_PROTOCOL_UDP_H
+#define HICN_PROTOCOL_UDP_H
+
+/*
+ * The len of the UDP header struct must be 8 bytes.
+ */
+#define EXPECTED_UDP_HDRLEN 8
+
+typedef struct
+{
+ u16 src_port;
+ u16 dst_port;
+ u16 len;
+ u16 checksum;
+} _udp_header_t;
+
+#define UDP_HDRLEN sizeof (_udp_header_t)
+static_assert (EXPECTED_UDP_HDRLEN == UDP_HDRLEN,
+ "Size of UDP struct does not match its expected size.");
+
+#endif /* HICN_PROTOCOL_UDP_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/test/CMakeLists.txt b/lib/src/test/CMakeLists.txt
index 3e3c025c7..17cf835d2 100644
--- a/lib/src/test/CMakeLists.txt
+++ b/lib/src/test/CMakeLists.txt
@@ -22,6 +22,12 @@ list(APPEND TESTS_SRC
test_new_header.cc
test_udp_header.cc
test_validation.cc
+ test_bitmap.cc
+ test_interest_manifest.cc
+ test_khash.cc
+ test_pool.cc
+ test_ring.cc
+ test_vector.cc
)
##############################################################
diff --git a/lib/src/test/test_bitmap.cc b/lib/src/test/test_bitmap.cc
new file mode 100644
index 000000000..7fc8eef71
--- /dev/null
+++ b/lib/src/test/test_bitmap.cc
@@ -0,0 +1,261 @@
+/*
+ * 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>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+extern "C"
+{
+#define WITH_TESTS
+#include <hicn/util/bitmap.h>
+}
+
+#define DEFAULT_SIZE 10
+
+class BitmapTest : public ::testing::Test
+{
+protected:
+ BitmapTest () {}
+
+ virtual ~BitmapTest () {}
+
+ bitmap_t *bitmap;
+};
+
+/*
+ * TEST: bitmap allocation
+ */
+TEST_F (BitmapTest, BitmapAllocation)
+{
+ int rc;
+
+ /*
+ * We take a value < 32 on purpose to avoid confusion on the choice of a 32
+ * or 64 bit integer for storage
+ */
+ size_t size_not_pow2 = DEFAULT_SIZE;
+ bitmap_init (bitmap, size_not_pow2, 0);
+
+ /*
+ * Bitmap should have been allocated with a size rounded to the next power
+ * of 2
+ */
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL);
+
+ /* By default, no element should be set */
+ EXPECT_FALSE (bitmap_is_set (bitmap, 0));
+ EXPECT_TRUE (bitmap_is_unset (bitmap, 0));
+
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL);
+
+ EXPECT_FALSE (bitmap_is_set (bitmap, size_not_pow2 - 1));
+ EXPECT_TRUE (bitmap_is_unset (bitmap, size_not_pow2 - 1));
+
+ /* Bitmap should not have been reallocated */
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL);
+
+ /* After setting a bit after the end, bitmap should have been reallocated */
+ bitmap_set (bitmap, sizeof (bitmap[0]) * 8 - 1);
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL);
+
+ /* After setting a bit after the end, bitmap should have been reallocated */
+ rc = bitmap_set (bitmap, sizeof (bitmap[0]) * 8);
+ EXPECT_GE (rc, 0);
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 2UL);
+
+ rc = bitmap_set (bitmap, sizeof (bitmap[0]) * 8 + 1);
+ EXPECT_GE (rc, 0);
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 2UL);
+
+ bitmap_free (bitmap);
+
+ size_t size_pow2 = 16;
+
+ /* Limiting test for allocation size */
+ bitmap_init (bitmap, size_pow2, 0);
+ EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL);
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapSet)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ bitmap_set (bitmap, 20);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 20));
+ EXPECT_FALSE (bitmap_is_unset (bitmap, 20));
+ EXPECT_FALSE (bitmap_is_set (bitmap, 19));
+ EXPECT_TRUE (bitmap_is_unset (bitmap, 19));
+
+ // Test edge cases (i.e. start and end of block)
+ off_t start_position = 0;
+ bitmap_set (bitmap, start_position);
+ EXPECT_TRUE (bitmap_is_set (bitmap, start_position));
+ EXPECT_FALSE (bitmap_is_unset (bitmap, start_position));
+
+ off_t end_position = BITMAP_WIDTH (bitmap) - 1;
+ bitmap_set (bitmap, end_position);
+ EXPECT_TRUE (bitmap_is_set (bitmap, end_position));
+ EXPECT_FALSE (bitmap_is_unset (bitmap, end_position));
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapUnSet)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ bitmap_set (bitmap, 20);
+ bitmap_set (bitmap, 19);
+ bitmap_unset (bitmap, 20);
+ EXPECT_FALSE (bitmap_is_set (bitmap, 20));
+ EXPECT_TRUE (bitmap_is_unset (bitmap, 20));
+ EXPECT_TRUE (bitmap_is_set (bitmap, 19));
+ EXPECT_FALSE (bitmap_is_unset (bitmap, 19));
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapSetTo)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ bitmap_set_to (bitmap, 40);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 20));
+ EXPECT_TRUE (bitmap_is_set (bitmap, 21));
+ EXPECT_TRUE (bitmap_is_unset (bitmap, 41));
+ EXPECT_TRUE (bitmap_is_unset (bitmap, 42));
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapFirstSet)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ // Get first set bit. It should be INVALID_INDEX
+ EXPECT_EQ (bitmap_first_set (bitmap), BITMAP_INVALID_INDEX);
+
+ // set bit 40
+ bitmap_set (bitmap, 40);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 40));
+
+ // Get first set bit. It should be bit 40 (surprise):)
+ EXPECT_EQ (bitmap_first_set (bitmap), hicn_uword (40));
+
+ // set bit 3
+ bitmap_set (bitmap, 3);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 3));
+
+ // The first set bit now should be bit #3
+ EXPECT_EQ (bitmap_first_set (bitmap), hicn_uword (3));
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapFirstUnSet)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ // Get first unset bit. It should be 0
+ EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (0));
+
+ // set bit 0
+ bitmap_set (bitmap, 0);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 0));
+
+ // Get first unset bit. It should be bit 1
+ EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (1));
+
+ // set bit 3
+ bitmap_set (bitmap, 3);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 3));
+
+ // The first set bit now should be still 1
+ EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (1));
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapNextSet)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ // Get next unset bit >= 0. It should be INVALID
+ EXPECT_EQ (bitmap_next_set (bitmap, 0), BITMAP_INVALID_INDEX);
+
+ // set bit 0
+ bitmap_set (bitmap, 0);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 0));
+
+ // Get next set bit >= 0. It should be bit 0
+ EXPECT_EQ (bitmap_next_set (bitmap, 0), hicn_uword (0));
+
+ // set bit 3
+ bitmap_set (bitmap, 3);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 3));
+
+ // Get next set bit >= 1. It should be 3
+ EXPECT_EQ (bitmap_next_set (bitmap, 1), hicn_uword (3));
+
+ // set (N-2)th bit
+ bitmap_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2);
+ EXPECT_TRUE (bitmap_is_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2));
+ EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 3),
+ DEFAULT_SIZE * WORD_WIDTH - 2);
+
+ // set (N-1)th bit
+ bitmap_unset (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2);
+ bitmap_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1);
+ EXPECT_TRUE (bitmap_is_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1));
+ EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2),
+ DEFAULT_SIZE * WORD_WIDTH - 1);
+ EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1),
+ DEFAULT_SIZE * WORD_WIDTH - 1);
+
+ bitmap_free (bitmap);
+}
+
+TEST_F (BitmapTest, BitmapNextUnSet)
+{
+ bitmap_init (bitmap, DEFAULT_SIZE, 0);
+
+ // Get next unset bit >= 0. It should be 0
+ EXPECT_EQ (bitmap_next_unset (bitmap, 0), hicn_uword (0));
+
+ // set bit 0
+ bitmap_set (bitmap, 0);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 0));
+
+ // Get next set bit >= 0. It should be bit 1
+ EXPECT_EQ (bitmap_next_unset (bitmap, 0), hicn_uword (1));
+
+ // set bit 3
+ bitmap_set (bitmap, 3);
+ EXPECT_TRUE (bitmap_is_set (bitmap, 3));
+
+ // Get next unset bit after 3. It should be 4
+ EXPECT_EQ (bitmap_next_unset (bitmap, 3), hicn_uword (4));
+
+ bitmap_free (bitmap);
+}
diff --git a/lib/src/test/test_interest_manifest.cc b/lib/src/test/test_interest_manifest.cc
new file mode 100644
index 000000000..c912b0bc6
--- /dev/null
+++ b/lib/src/test/test_interest_manifest.cc
@@ -0,0 +1,86 @@
+/*
+ * 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>
+
+extern "C"
+{
+#include <hicn/interest_manifest.h>
+}
+
+static constexpr hicn_uword WORD_SIZE = WORD_WIDTH;
+
+class InterestManifestTest : public ::testing::Test
+{
+protected:
+ InterestManifestTest () {}
+ virtual ~InterestManifestTest () {}
+};
+
+TEST_F (InterestManifestTest, OneWordBitmapUpdate)
+{
+ hicn_uword initial_bitmap[1];
+ hicn_uword curr_bitmap[1] = { 0 };
+ initial_bitmap[0] =
+ 0x0000000000000b07; // ...000000000000000000000101100000111
+
+ // Consume first 4 'one' bits (i.e. suffixes), reaching position 9
+ size_t pos = 0, max_suffixes = 4;
+ pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap, pos,
+ WORD_SIZE, max_suffixes);
+ EXPECT_EQ (pos, std::size_t (9));
+ EXPECT_EQ (curr_bitmap[0], hicn_uword (0x0000000000000107));
+
+ // Consume the remaining 2 'one' bits, reaching end of bitmap
+ hicn_uword curr_bitmap2[1] = { 0 };
+ pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap2, pos,
+ WORD_SIZE, max_suffixes);
+ EXPECT_EQ (pos, WORD_SIZE);
+ EXPECT_EQ (curr_bitmap2[0], hicn_uword (0x00000a00));
+
+ // Consume all suffixes at once
+ hicn_uword curr_bitmap3[1] = { 0 };
+ max_suffixes = 16;
+ pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap3, 0,
+ WORD_SIZE, max_suffixes);
+ EXPECT_EQ (pos, WORD_SIZE);
+ EXPECT_EQ (curr_bitmap3[0], initial_bitmap[0]);
+}
+
+TEST_F (InterestManifestTest, TwoWordBitmapUpdate)
+{
+ hicn_uword initial_bitmap[2];
+ initial_bitmap[0] = 0x0000000000000b07;
+ initial_bitmap[1] = 0x0000000000000b07;
+ // -> 0000000000000000000010110000011100000000000000000000101100000111
+
+ int expected_pos[] = { WORD_SIZE + 2, 2 * WORD_SIZE };
+ u32 expected_bitmap[][2] = { { 0x00000b07, 0x00000003 },
+ { 0x0, 0x00000b04 } };
+
+ // Loop to consume all suffixes
+ int pos = 0, max_suffixes = 8, i = 0, len = WORD_SIZE * 2;
+ while (pos != len)
+ {
+ hicn_uword curr_bitmap[2] = { 0 };
+ pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap, pos,
+ len, max_suffixes);
+
+ EXPECT_EQ (pos, expected_pos[i]);
+ EXPECT_EQ (curr_bitmap[0], expected_bitmap[i][0]);
+ EXPECT_EQ (curr_bitmap[1], expected_bitmap[i][1]);
+ i++;
+ }
+} \ No newline at end of file
diff --git a/lib/src/test/test_khash.cc b/lib/src/test/test_khash.cc
new file mode 100644
index 000000000..b0423ab5d
--- /dev/null
+++ b/lib/src/test/test_khash.cc
@@ -0,0 +1,179 @@
+/*
+ * 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>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+extern "C"
+{
+#include <hicn/util/khash.h>
+}
+
+KHASH_MAP_INIT_INT (int, unsigned char)
+
+typedef struct
+{
+ unsigned key;
+ unsigned char val;
+} int_unpack_t;
+
+typedef struct
+{
+ unsigned key;
+ unsigned char val;
+} __attribute__ ((__packed__)) int_packed_t;
+
+#define hash_eq(a, b) ((a).key == (b).key)
+#define hash_func(a) ((a).key)
+
+KHASH_INIT (iun, int_unpack_t, char, 0, hash_func, hash_eq)
+KHASH_INIT (ipk, int_packed_t, char, 0, hash_func, hash_eq)
+
+class KHashTest : public ::testing::Test
+{
+protected:
+ KHashTest () {}
+
+ virtual ~KHashTest ()
+ {
+ // You can do clean-up work that doesn't throw exceptions here.
+ }
+
+ // If the constructor and destructor are not enough for setting up
+ // and cleaning up each test, you can define the following methods:
+
+ virtual void
+ SetUp ()
+ {
+ khash = kh_init (int);
+ }
+
+ virtual void
+ TearDown ()
+ {
+ kh_destroy (int, khash);
+ }
+ khash_t (int) * khash;
+};
+
+TEST_F (KHashTest, KhashIntSize)
+{
+ int ret;
+ int k;
+ int size = kh_size (khash);
+
+ EXPECT_EQ (size, 0);
+ k = kh_put (int, khash, 10, &ret);
+ if (ret == 1)
+ {
+ kh_val (khash, k) = 10;
+ }
+ size = kh_size (khash);
+ EXPECT_EQ (size, 1);
+}
+
+TEST_F (KHashTest, KhashIntPut)
+{
+ int ret;
+ int k;
+ k = kh_put (int, khash, 10, &ret);
+ if (ret == 1)
+ {
+ kh_val (khash, k) = 10;
+ }
+ int size = kh_size (khash);
+ EXPECT_EQ (size, 1);
+ k = kh_put (int, khash, 20, &ret);
+ if (ret == 1)
+ {
+ kh_val (khash, k) = 20;
+ }
+ size = kh_size (khash);
+ EXPECT_EQ (size, 2);
+}
+
+TEST_F (KHashTest, KhashCheckValue)
+{
+ int ret;
+ int k;
+ k = kh_put (int, khash, 10, &ret);
+ if (ret == 1)
+ {
+ kh_val (khash, k) = 100;
+ }
+ k = kh_put (int, khash, 20, &ret);
+ if (ret == 1)
+ {
+ kh_val (khash, k) = 200;
+ }
+
+ k = kh_put (int, khash, 10, &ret);
+ int val = -1;
+ if (!ret)
+ val = kh_val (khash, k);
+ EXPECT_EQ (val, 100);
+
+ k = kh_put (int, khash, 20, &ret);
+ val = -1;
+ if (!ret)
+ val = kh_val (khash, k);
+ EXPECT_EQ (val, 200);
+}
+
+// Check that there are no collisions in case of same key hash
+typedef struct
+{
+ int x;
+} Key;
+#define hash_key(key) 1 // Hash is always 1 to simulate collisions
+#define key_hash_eq(a, b) (a->x == b->x) // Function used in case of collisions
+KHASH_INIT (test_map, const Key *, unsigned, 1, hash_key, key_hash_eq);
+
+TEST_F (KHashTest, Collisions)
+{
+ int ret;
+ khiter_t k;
+
+ kh_test_map_t *map = kh_init (test_map);
+ Key key1 = { .x = 10 };
+ Key key2 = { .x = 11 };
+
+ k = kh_put_test_map (map, &key1, &ret);
+ EXPECT_EQ (ret, 1);
+ kh_val (map, k) = 15;
+
+ k = kh_put_test_map (map, &key2, &ret);
+ EXPECT_EQ (ret, 1);
+ kh_val (map, k) = 27;
+
+ k = kh_get_test_map (map, &key1);
+ ASSERT_NE (k, kh_end (map));
+ unsigned val = kh_val (map, k);
+ EXPECT_EQ (val, 15u);
+
+ k = kh_get_test_map (map, &key2);
+ ASSERT_NE (k, kh_end (map));
+ val = kh_val (map, k);
+ EXPECT_EQ (val, 27u);
+
+ kh_destroy_test_map (map);
+}
diff --git a/lib/src/test/test_name.cc b/lib/src/test/test_name.cc
index 207725adb..35e636b63 100644
--- a/lib/src/test/test_name.cc
+++ b/lib/src/test/test_name.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -58,32 +58,24 @@ protected:
// The hash should be equal, with and without considering the suffix
uint32_t hash_a, hash_b;
- rc = hicn_name_hash (&name_a, &hash_a, 1);
- EXPECT_EQ (rc, 0);
- rc = hicn_name_hash (&name_b, &hash_b, 1);
- EXPECT_EQ (rc, 0);
+ hash_a = hicn_name_get_hash (&name_a);
+ hash_b = hicn_name_get_hash (&name_b);
EXPECT_EQ (hash_a, hash_b);
- rc = hicn_name_hash (&name_a, &hash_a, 0);
- EXPECT_EQ (rc, 0);
- rc = hicn_name_hash (&name_b, &hash_b, 0);
- EXPECT_EQ (rc, 0);
+ hash_a = hicn_name_get_prefix_hash (&name_a);
+ hash_b = hicn_name_get_prefix_hash (&name_b);
EXPECT_EQ (hash_a, hash_b);
// Now let's change the suffix
- rc = hicn_name_set_seq_number (&name_a, 97531);
+ rc = hicn_name_set_suffix (&name_a, 97531);
// They should result equal if we do not consider the suffix
- rc = hicn_name_hash (&name_a, &hash_a, 0);
- EXPECT_EQ (rc, 0);
- rc = hicn_name_hash (&name_b, &hash_b, 0);
- EXPECT_EQ (rc, 0);
+ hash_a = hicn_name_get_prefix_hash (&name_a);
+ hash_b = hicn_name_get_prefix_hash (&name_b);
EXPECT_EQ (hash_a, hash_b);
// And different if we consider it
- rc = hicn_name_hash (&name_a, &hash_a, 1);
- EXPECT_EQ (rc, 0);
- rc = hicn_name_hash (&name_b, &hash_b, 1);
- EXPECT_EQ (rc, 0);
+ hash_a = hicn_name_get_hash (&name_a);
+ hash_b = hicn_name_get_hash (&name_b);
EXPECT_NE (hash_a, hash_b);
}
@@ -120,7 +112,7 @@ protected:
EXPECT_EQ (rc, 0);
// Now let's change the suffix
- rc = hicn_name_set_seq_number (&name_a, 97531);
+ rc = hicn_name_set_suffix (&name_a, 97531);
// They should result equal if we do not consider the suffix
rc = hicn_name_compare (&name_a, &name_b, 0);
EXPECT_EQ (rc, 0);
@@ -130,13 +122,13 @@ protected:
}
void
- nameFromIpPrefixTest (const ip_prefix_t &ip_prefix)
+ nameFromIpPrefixTest (const hicn_ip_prefix_t &hicn_ip_prefix)
{
uint32_t suffix = 54321;
hicn_name_t name;
- int rc = hicn_name_create_from_ip_prefix (&ip_prefix, suffix, &name);
+ int rc = hicn_name_create_from_ip_prefix (&hicn_ip_prefix, suffix, &name);
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
- rc = memcmp (ip_prefix.address.v6.as_u8, name.prefix.v6.as_u8,
+ rc = memcmp (hicn_ip_prefix.address.v6.as_u8, name.prefix.v6.as_u8,
sizeof (name.prefix.v6));
EXPECT_EQ (rc, 0);
EXPECT_EQ (suffix, name.suffix);
@@ -154,16 +146,16 @@ protected:
int family;
rc = hicn_name_get_family (&name, &family);
- ip_prefix_t ip_prefix;
- rc = hicn_name_to_ip_prefix (&name, &ip_prefix);
+ hicn_ip_prefix_t hicn_ip_prefix;
+ rc = hicn_name_to_hicn_ip_prefix (&name, &hicn_ip_prefix);
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
- EXPECT_EQ (ip_prefix.family, family);
- rc = ip_address_cmp (&ip_prefix.address, &name.prefix, AF_INET6);
+ EXPECT_EQ (hicn_ip_prefix.family, family);
+ rc = hicn_ip_address_cmp (&hicn_ip_prefix.address, &name.prefix);
EXPECT_EQ (rc, 0);
}
hicn_name_t name_, name4_, name6_;
- ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes;
+ hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes;
};
/**
@@ -180,7 +172,7 @@ TEST_F (NameTest, NameInitialization)
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
// Check name is correctly created
- rc = ip_address_cmp (&name6.prefix, &ipv6_prefix_bytes, AF_INET6);
+ rc = hicn_ip_address_cmp (&name6.prefix, &ipv6_prefix_bytes);
EXPECT_EQ (rc, 0);
EXPECT_EQ (name6.suffix, suffix);
@@ -190,7 +182,7 @@ TEST_F (NameTest, NameInitialization)
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
// Check name is correctly created
- rc = ip_address_cmp (&name4.prefix, &ipv4_prefix_bytes, AF_INET);
+ rc = hicn_ip_address_cmp (&name4.prefix, &ipv4_prefix_bytes);
EXPECT_EQ (name4.prefix.pad[0], 0UL);
EXPECT_EQ (name4.prefix.pad[1], 0UL);
EXPECT_EQ (name4.prefix.pad[2], 0UL);
@@ -202,7 +194,7 @@ TEST_F (NameTest, NameInitialization)
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
// Check name is correctly created
- rc = ip_address_cmp (&name6.prefix, &ipv4_prefix_bytes, AF_INET);
+ rc = hicn_ip_address_cmp (&name6.prefix, &ipv4_prefix_bytes);
EXPECT_EQ (name6.prefix.pad[0], 0UL);
EXPECT_EQ (name6.prefix.pad[1], 0UL);
EXPECT_EQ (name6.prefix.pad[2], 0UL);
@@ -215,22 +207,26 @@ TEST_F (NameTest, NameInitialization)
*/
TEST_F (NameTest, NameFromIpPrefix6)
{
- ip_prefix_t ip_prefix = { .family = AF_INET6, .address = {}, .len = 64 };
+ hicn_ip_prefix_t hicn_ip_prefix = { .family = AF_INET6,
+ .address = {},
+ .len = 64 };
- ip_prefix.address.v6.as_u64[0] = ipv6_prefix_bytes.v6.as_u64[0];
- ip_prefix.address.v6.as_u64[1] = ipv6_prefix_bytes.v6.as_u64[1];
+ hicn_ip_prefix.address.v6.as_u64[0] = ipv6_prefix_bytes.v6.as_u64[0];
+ hicn_ip_prefix.address.v6.as_u64[1] = ipv6_prefix_bytes.v6.as_u64[1];
- nameFromIpPrefixTest (ip_prefix);
+ nameFromIpPrefixTest (hicn_ip_prefix);
}
TEST_F (NameTest, NameFromIpPrefix4)
{
- ip_prefix_t ip_prefix = { .family = AF_INET, .address = {}, .len = 64 };
- ip_prefix.address.v4.as_u32 = ipv4_prefix_bytes.v4.as_u32;
- ip_prefix.address.pad[0] = 0;
- ip_prefix.address.pad[1] = 0;
- ip_prefix.address.pad[2] = 0;
- nameFromIpPrefixTest (ip_prefix);
+ hicn_ip_prefix_t hicn_ip_prefix = { .family = AF_INET,
+ .address = {},
+ .len = 64 };
+ hicn_ip_prefix.address.v4.as_u32 = ipv4_prefix_bytes.v4.as_u32;
+ hicn_ip_prefix.address.pad[0] = 0;
+ hicn_ip_prefix.address.pad[1] = 0;
+ hicn_ip_prefix.address.pad[2] = 0;
+ nameFromIpPrefixTest (hicn_ip_prefix);
}
TEST_F (NameTest, NameCompare6) { nameCompareTest (ipv6_prefix); }
@@ -257,8 +253,8 @@ TEST_F (NameTest, NameCopy4) { nameCopyTest (ipv4_prefix); }
TEST_F (NameTest, NameCopyToDestination)
{
- ip4_address_t dst4;
- ip6_address_t dst6;
+ ipv4_address_t dst4;
+ ipv6_address_t dst6;
// Copy names to destination
int rc = hicn_name_copy_prefix_to_destination (dst4.as_u8, &name4_);
@@ -282,7 +278,7 @@ TEST_F (NameTest, SetGetSuffix)
EXPECT_EQ (suffix, suffix_ret);
// Set new suffix
- rc = hicn_name_set_seq_number (&name6_, suffix2);
+ rc = hicn_name_set_suffix (&name6_, suffix2);
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
// Check suffix was set
diff --git a/lib/src/test/test_new_header.cc b/lib/src/test/test_new_header.cc
index 33c9e13c9..c936b6910 100644
--- a/lib/src/test/test_new_header.cc
+++ b/lib/src/test/test_new_header.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -20,10 +20,10 @@ extern "C"
#include <hicn/name.h>
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/protocol/new.h>
-#include <hicn/protocol/ah.h>
-#include <hicn/header.h>
-#include <hicn/compat.h>
+#include <hicn/packet.h>
+
+#include "../protocol/ah.h"
+#include "../protocol/new.h"
}
class NewHeaderTest : public ::testing::Test
@@ -33,10 +33,11 @@ protected:
const char *ipv4_prefix = "12.13.14.15";
const uint32_t suffix = 12345;
- NewHeaderTest (size_t hdr_size, hicn_format_t format)
- : buffer_ (new uint8_t[hdr_size]), header_ ((hicn_header_t *) (buffer_)),
+ NewHeaderTest (hicn_packet_format_t format)
+ : buffer_ (new uint8_t[NEW_HDRLEN]),
format_ (format), name_{}, name4_{}, name6_{}
{
+
int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6);
EXPECT_EQ (rc, 1);
@@ -49,42 +50,46 @@ protected:
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
}
- NewHeaderTest () : NewHeaderTest (NEW_HDRLEN, HF_NEW) {}
+ NewHeaderTest () : NewHeaderTest (HICN_PACKET_FORMAT_NEW) {}
virtual ~NewHeaderTest () { delete[] buffer_; }
void
- checkCommon (const _new_header_t *new_hdr)
+ checkCommon ()
{
// Initialize header
- int rc = hicn_packet_init_header (format_, header_);
+ hicn_packet_set_format (&pkbuf_, format_);
+ // pkbuf_set_type (&pkbuf_, HICN_PACKET_TYPE_UNDEFINED);
+ int rc = hicn_packet_init_header (&pkbuf_, 0);
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
+ auto new_hdr = (_new_header_t *) buffer_;
+
// Check fields
EXPECT_EQ (new_hdr->prefix.v6.as_u64[0], 0UL);
EXPECT_EQ (new_hdr->prefix.v6.as_u64[1], 0UL);
EXPECT_EQ (new_hdr->suffix, 0UL);
EXPECT_EQ (new_hdr->lifetime, 0UL);
EXPECT_EQ (new_hdr->path_label, 0UL);
- EXPECT_EQ (new_hdr->payload_length, 0UL);
+ EXPECT_EQ (new_hdr->payload_len, 0UL);
EXPECT_EQ (_get_new_header_version (new_hdr), 0x9);
+ EXPECT_EQ (new_hdr->flags, 0);
}
virtual void
SetUp () override
{
- auto new_hdr = &header_->protocol.newhdr;
- checkCommon (new_hdr);
- EXPECT_EQ (new_hdr->flags, 0);
+ checkCommon ();
}
uint8_t *buffer_;
- hicn_header_t *header_;
- hicn_format_t format_;
+ hicn_packet_buffer_t pkbuf_;
+ hicn_packet_format_t format_;
hicn_name_t name_, name4_, name6_;
- ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes;
+ hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes;
};
+#if 0
class NewHeaderAHTest : public NewHeaderTest
{
protected:
@@ -229,7 +234,7 @@ TEST_F (NewHeaderTest, SetGetName)
TEST_F (NewHeaderTest, SetGetLocator)
{
// This function does nothing but it is set for compatibility
- ip_address_t locator;
+ hicn_ip_address_t locator;
memset (&locator, 0, sizeof (locator));
locator.v6.as_u8[15] = 1;
int rc = hicn_packet_set_interest (format_, header_);
@@ -338,3 +343,4 @@ TEST_F (NewHeaderTest, SetGetPayloadType)
EXPECT_EQ (payload_type, payload_type_ret);
}
+#endif
diff --git a/lib/src/test/test_pool.cc b/lib/src/test/test_pool.cc
new file mode 100644
index 000000000..cbb5ce068
--- /dev/null
+++ b/lib/src/test/test_pool.cc
@@ -0,0 +1,209 @@
+/*
+ * 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>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+extern "C"
+{
+#define WITH_TESTS
+#include <hicn/util/pool.h>
+}
+
+/*
+ * TODO
+ * - test max_size
+ */
+
+#define DEFAULT_SIZE 10
+
+class PoolTest : public ::testing::Test
+{
+protected:
+ PoolTest () {}
+ virtual ~PoolTest () {}
+
+ int *pool;
+};
+
+TEST_F (PoolTest, PoolAllocation)
+{
+ int rc;
+
+ pool_init (pool, DEFAULT_SIZE, 0);
+
+ size_t pool_size = next_pow2 (DEFAULT_SIZE);
+
+ EXPECT_EQ (pool_get_alloc_size (pool), pool_size);
+
+ /* Check that free indices and bitmaps are correctly initialize */
+ off_t *fi = pool_get_free_indices (pool);
+ EXPECT_EQ (vector_len (fi), pool_size);
+ EXPECT_EQ (fi[0], (long) (pool_size - 1));
+ EXPECT_EQ (fi[pool_size - 1], 0);
+
+ /* The allocated size of the underlying vector should be the next power of
+ * two
+ */
+ EXPECT_EQ (vector_get_alloc_size (fi), pool_size);
+
+ bitmap_t *fb = pool_get_free_bitmap (pool);
+ EXPECT_TRUE (bitmap_is_set (fb, 0));
+ EXPECT_TRUE (bitmap_is_set (fb, pool_size - 2));
+ EXPECT_TRUE (bitmap_is_set (fb, pool_size - 1));
+ EXPECT_TRUE (bitmap_is_unset (fb, pool_size));
+
+ /* Getting elements from the pool should correctly update the free indices
+ * and bitmap */
+ int *elt;
+
+ rc = pool_get (pool, elt);
+ EXPECT_GE (rc, 0);
+ EXPECT_EQ (vector_len (fi), pool_size - 1);
+ EXPECT_TRUE (bitmap_is_unset (fb, 0));
+
+ rc = pool_get (pool, elt);
+ EXPECT_GE (rc, 0);
+ EXPECT_EQ (vector_len (fi), pool_size - 2);
+ EXPECT_TRUE (bitmap_is_unset (fb, 1));
+
+ for (unsigned i = 0; i < pool_size - 4; i++)
+ {
+ rc = pool_get (pool, elt);
+ EXPECT_GE (rc, 0);
+ }
+
+ rc = pool_get (pool, elt);
+ EXPECT_GE (rc, 0);
+ EXPECT_EQ (vector_len (fi), 1UL);
+ EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 2));
+
+ rc = pool_get (pool, elt);
+ EXPECT_GE (rc, 0);
+ EXPECT_EQ (vector_len (fi), 0UL);
+ EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 1));
+
+ /*
+ * Getting elements within the allocated range should not have triggered a
+ * resize
+ */
+ EXPECT_EQ (pool_len (pool), pool_size);
+
+ /*
+ * Getting elements once the allocated range has been exceeded should
+ * trigger a resize
+ */
+ rc = pool_get (pool, elt);
+ EXPECT_GE (rc, 0);
+
+ EXPECT_EQ (pool_get_alloc_size (pool), pool_size * 2);
+
+ EXPECT_EQ (pool_len (pool), pool_size + 1);
+
+ /*
+ * Doubling the size, we should have again pool_size elements free, minus 1
+ */
+ EXPECT_EQ (pool_get_free_indices_size (pool), pool_size - 1);
+
+ /*
+ * NOTE: this is wrong as there has been a realloc and the old fi
+ * pointer is now invalid
+ */
+ // EXPECT_EQ(vector_len(fi), pool_size - 1);
+
+ /* And the bitmap should also be correctly modified */
+ fb = pool_get_free_bitmap (pool);
+ EXPECT_TRUE (bitmap_is_unset (fb, pool_size));
+
+ /* Check that surrounding values are also correct */
+ EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 1));
+ EXPECT_TRUE (bitmap_is_set (fb, pool_size + 1));
+
+ /* Setting elements after should through */
+
+ /* Check that free indices and bitmaps are correctly updated */
+
+ pool_free (pool);
+}
+
+TEST_F (PoolTest, PoolPut)
+{
+ pool_init (pool, DEFAULT_SIZE, 0);
+
+ int *elt;
+ pool_get (pool, elt);
+ *elt = 10;
+ pool_put (pool, elt);
+
+ pool_free (pool);
+}
+
+TEST_F (PoolTest, PoolGetForceBitmapRealloc)
+{
+ const int N = 64;
+ int *elts[N];
+ int *elt = NULL;
+ pool_init (pool, N, 0);
+
+ for (int i = 0; i < N; i++)
+ pool_get (pool, elts[i]);
+ pool_get (pool, elt);
+
+ pool_free (pool);
+}
+
+TEST_F (PoolTest, PoolGetAfterReleasing)
+{
+ int *elt1 = NULL, *elt2 = NULL, *tmp = NULL;
+ pool_init (pool, DEFAULT_SIZE, 0);
+
+ // If two elements are requested...
+ off_t id1 = pool_get (pool, elt1);
+ pool_get (pool, tmp);
+
+ // ...and the first one is released...
+ pool_put (pool, elt1);
+
+ // ...requesting a new one should return
+ // the first one (that was freed)
+ off_t id2 = pool_get (pool, elt2);
+ EXPECT_EQ (id1, id2);
+ EXPECT_EQ (elt1, elt2);
+
+ pool_free (pool);
+}
+
+TEST_F (PoolTest, PoolGetMultipleElementsAfterReleasing)
+{
+ const int N = 2;
+ int *elts[N];
+ pool_init (pool, N, 0);
+
+ for (int i = 0; i < N; i++)
+ pool_get (pool, elts[i]);
+ for (int i = 0; i < N; i++)
+ pool_put (pool, elts[i]);
+ for (int i = 0; i < N; i++)
+ pool_get (pool, elts[i]);
+
+ pool_free (pool);
+}
diff --git a/lib/src/test/test_ring.cc b/lib/src/test/test_ring.cc
new file mode 100644
index 000000000..f0b0371e8
--- /dev/null
+++ b/lib/src/test/test_ring.cc
@@ -0,0 +1,104 @@
+/*
+ * 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>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+extern "C"
+{
+#define WITH_TESTS
+#include <hicn/util/ring.h>
+}
+
+#define DEFAULT_SIZE 10UL
+
+class RingTest : public ::testing::Test
+{
+protected:
+ RingTest () { ring_init (ring, DEFAULT_SIZE); }
+ virtual ~RingTest () { ring_free (ring); }
+
+ int *ring = NULL;
+};
+
+/* TEST: Ring allocation and initialization */
+TEST_F (RingTest, RingAddOne)
+{
+ int val = -1;
+ /* Allocated size should be the next power of two */
+ EXPECT_EQ (ring_get_size (ring), 0UL);
+ ring_add_value (ring, 1);
+ EXPECT_EQ (ring_get_size (ring), 1UL);
+ ring_get (ring, 0, &val);
+ EXPECT_EQ (val, 1);
+ EXPECT_EQ (ring_get_size (ring), 1UL);
+ ring_advance (ring, 1);
+ EXPECT_EQ (ring_get_size (ring), 0UL);
+}
+
+TEST_F (RingTest, RingAddMany)
+{
+ size_t i = 0;
+ int val = -1;
+ size_t count = 0;
+
+ /* Allocated size should be the next power of two */
+ EXPECT_EQ (ring_get_size (ring), 0UL);
+ for (unsigned i = 0; i < DEFAULT_SIZE; i++)
+ ring_add_value (ring, i);
+ EXPECT_EQ (ring_get_size (ring), DEFAULT_SIZE);
+
+ count = 0;
+ ring_enumerate_n (ring, i, &val, 1, {
+ EXPECT_EQ (val, (int) (i));
+ count++;
+ });
+ EXPECT_EQ (count, 1UL);
+
+ count = 0;
+ ring_enumerate_n (ring, i, &val, DEFAULT_SIZE, {
+ EXPECT_EQ (val, (int) (i));
+ count++;
+ });
+ EXPECT_EQ (count, DEFAULT_SIZE);
+
+ count = 0;
+ ring_enumerate_n (ring, i, &val, DEFAULT_SIZE + 1, {
+ EXPECT_EQ (val, (int) (i));
+ count++;
+ });
+ EXPECT_EQ (count, DEFAULT_SIZE);
+
+ // Drop one
+ ring_add_value (ring, DEFAULT_SIZE);
+ EXPECT_EQ (ring_get_size (ring), DEFAULT_SIZE);
+
+ count = 0;
+ ring_enumerate_n (ring, i, &val, DEFAULT_SIZE, {
+ EXPECT_EQ (val, (int) (i + 1)); // all values shoud be shifted
+ count++;
+ });
+ EXPECT_EQ (count, DEFAULT_SIZE);
+
+ ring_advance (ring, DEFAULT_SIZE);
+ EXPECT_EQ (ring_get_size (ring), 0UL);
+}
diff --git a/lib/src/test/test_udp_header.cc b/lib/src/test/test_udp_header.cc
index 5d9f4d1eb..2853ee31b 100644
--- a/lib/src/test/test_udp_header.cc
+++ b/lib/src/test/test_udp_header.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -20,10 +20,12 @@ extern "C"
#include <hicn/name.h>
#include <hicn/common.h>
#include <hicn/error.h>
-#include <hicn/protocol/new.h>
-#include <hicn/protocol/ah.h>
-#include <hicn/header.h>
-#include <hicn/compat.h>
+#include <hicn/packet.h>
+
+#include "../protocol/ah.h"
+#include "../protocol/ipv6.h"
+#include "../protocol/udp.h"
+#include "../protocol/new.h"
}
class UdpHeaderTest : public ::testing::Test
@@ -33,8 +35,8 @@ protected:
const char *ipv4_prefix = "12.13.14.15";
const uint32_t suffix = 12345;
- UdpHeaderTest (size_t hdr_size, hicn_format_t format)
- : buffer_ (new uint8_t[hdr_size]), header_ ((hicn_header_t *) (buffer_)),
+ UdpHeaderTest (size_t hdr_size, hicn_packet_format_t format)
+ : buffer_ (new uint8_t[hdr_size]), hdr_size_ (hdr_size),
format_ (format), name_{}, name4_{}, name6_{}
{
int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6);
@@ -50,19 +52,26 @@ protected:
}
UdpHeaderTest ()
- : UdpHeaderTest (NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, HF_INET6_UDP)
+ : UdpHeaderTest (NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN,
+ HICN_PACKET_FORMAT_IPV6_UDP)
{
}
virtual ~UdpHeaderTest () { delete[] buffer_; }
+ // checked everytime we build the packet...
void
- checkCommon (const _ipv6_header_t *ip6_hdr)
+ checkCommon ()
{
- // Initialize header
- int rc = hicn_packet_init_header (format_, header_);
+ /* Initialize packet buffer headers */
+ hicn_packet_set_format (&pkbuf_, format_);
+ hicn_packet_set_type (&pkbuf_, HICN_PACKET_TYPE_INTEREST);
+ hicn_packet_set_buffer (&pkbuf_, buffer_, hdr_size_, 0);
+ int rc = hicn_packet_init_header (&pkbuf_, 0);
EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
+ auto ip6_hdr = (_ipv6_header_t *) buffer_;
+
// Check fields
EXPECT_EQ (ip6_hdr->saddr.as_u64[0], 0UL);
EXPECT_EQ (ip6_hdr->saddr.as_u64[1], 0UL);
@@ -82,22 +91,22 @@ protected:
EXPECT_EQ (new_hdr->suffix, 0UL);
EXPECT_EQ (new_hdr->lifetime, 0UL);
EXPECT_EQ (new_hdr->path_label, 0UL);
- EXPECT_EQ (new_hdr->payload_length, 0UL);
+ EXPECT_EQ (new_hdr->payload_len, 0UL);
EXPECT_EQ (_get_new_header_version (new_hdr), 0x9);
}
virtual void
SetUp () override
{
- auto ip6_hdr = &header_->protocol.ipv6;
- checkCommon (ip6_hdr);
+ checkCommon ();
}
uint8_t *buffer_;
- hicn_header_t *header_;
- hicn_format_t format_;
+ size_t hdr_size_;
+ hicn_packet_buffer_t pkbuf_;
+ hicn_packet_format_t format_;
hicn_name_t name_, name4_, name6_;
- ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes;
+ hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes;
};
class UdpHeaderAHTest : public UdpHeaderTest
@@ -105,7 +114,7 @@ class UdpHeaderAHTest : public UdpHeaderTest
protected:
UdpHeaderAHTest ()
: UdpHeaderTest (AH_HDRLEN + NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN,
- HF_INET6_UDP_AH)
+ HICN_PACKET_FORMAT_IPV6_UDP_AH)
{
}
};
@@ -115,26 +124,21 @@ protected:
*/
TEST_F (UdpHeaderTest, GetFormat)
{
- // Get format from existing packet
- hicn_format_t format;
- int rc = hicn_packet_get_format (header_, &format);
- EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
-
- // Check it corresponds to the new header format
- EXPECT_EQ (format, HF_INET6_UDP);
+ hicn_packet_format_t format = hicn_packet_get_format (&pkbuf_);
+ EXPECT_EQ (format.as_u32, HICN_PACKET_FORMAT_IPV6_UDP.as_u32);
}
TEST_F (UdpHeaderAHTest, GetFormat)
{
// Get format from existing packet
- hicn_format_t format;
- int rc = hicn_packet_get_format (header_, &format);
- EXPECT_EQ (rc, HICN_LIB_ERROR_NONE);
+ hicn_packet_format_t format = hicn_packet_get_format (&pkbuf_);
// Check it corresponds to the new header format
- EXPECT_EQ (format, HF_INET6_UDP_AH);
+ EXPECT_EQ (format.as_u32, HICN_PACKET_FORMAT_IPV6_UDP_AH.as_u32);
}
+#if 0
+
// /**
// * @brief Checksum functions are not required, but we keep them for
// * compatibility.
@@ -244,7 +248,7 @@ TEST_F (UdpHeaderTest, SetGetName)
TEST_F (UdpHeaderTest, SetGetLocator)
{
// This function does nothing but it is set for compatibility
- ip_address_t locator;
+ hicn_ip_address_t locator;
memset (&locator, 0, sizeof (locator));
locator.v6.as_u8[15] = 1;
int rc = hicn_packet_set_interest (format_, header_);
@@ -353,3 +357,4 @@ TEST_F (UdpHeaderTest, SetGetPayloadType)
EXPECT_EQ (payload_type, payload_type_ret);
}
+#endif
diff --git a/lib/src/test/test_vector.cc b/lib/src/test/test_vector.cc
new file mode 100644
index 000000000..88b0bb7cf
--- /dev/null
+++ b/lib/src/test/test_vector.cc
@@ -0,0 +1,254 @@
+/*
+ * 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>
+
+extern "C"
+{
+#include <hicn/util/vector.h>
+}
+
+static constexpr size_t DEFAULT_SIZE = 10;
+static constexpr size_t N_ELEMENTS = 5;
+
+class VectorTest : public ::testing::Test
+{
+protected:
+ VectorTest () { vector_init (vector, DEFAULT_SIZE, 0); }
+ virtual ~VectorTest () { vector_free (vector); }
+
+ int *vector = NULL;
+};
+
+TEST_F (VectorTest, VectorAllocateAndResize)
+{
+ // Allocated size should be the next power of two
+ EXPECT_EQ (vector_get_alloc_size (vector), 16UL);
+
+ // Setting elements within the allocated size should not trigger a resize
+ vector_ensure_pos (vector, 15);
+ EXPECT_EQ (vector_get_alloc_size (vector), 16UL);
+
+ // Setting elements after should through
+ vector_ensure_pos (vector, 16);
+ EXPECT_EQ (vector_get_alloc_size (vector), 32UL);
+}
+
+TEST_F (VectorTest, VectorSize)
+{
+ EXPECT_EQ (vector_len (vector), size_t (0));
+
+ // Check size after pushing one element
+ vector_push (vector, 1);
+ EXPECT_EQ (vector_len (vector), size_t (1));
+
+ // Check size after pushing additional elements
+ vector_push (vector, 2);
+ vector_push (vector, 3);
+ EXPECT_EQ (vector_len (vector), size_t (3));
+
+ // Try adding multiple elements
+ const int n_elements_to_add = 5;
+ size_t expected_new_len = vector_len (vector) + n_elements_to_add;
+ for (int i = 0; i < n_elements_to_add; i++)
+ vector_push (vector, i);
+ EXPECT_EQ (vector_len (vector), expected_new_len);
+}
+
+TEST_F (VectorTest, VectorCheckValue)
+{
+ // Add elements
+ vector_push (vector, 109);
+ vector_push (vector, 200);
+ EXPECT_EQ (vector_at (vector, 0), 109);
+ EXPECT_EQ (vector_at (vector, 1), 200);
+
+ // Update element
+ vector_set (vector, 1, 400);
+ EXPECT_EQ (vector_at (vector, 1), 400);
+
+ // Add at last available position
+ size_t prev_size = vector_len (vector);
+ vector_set (vector, vector_len (vector) - 1, 123);
+ EXPECT_EQ (vector_at (vector, vector_len (vector) - 1), 123);
+ EXPECT_EQ (prev_size, vector_len (vector)) << "Size should not have changed";
+}
+
+TEST_F (VectorTest, RemoveElement)
+{
+ // Populate vector
+ for (size_t i = 0; i < N_ELEMENTS; i++)
+ vector_push (vector, i);
+ EXPECT_EQ (vector_len (vector), N_ELEMENTS);
+ for (size_t i = 0; i < vector_len (vector); i++)
+ EXPECT_EQ (vector_at (vector, i), (int) i);
+
+ // Remove element
+ int value_to_remove = 3;
+ int num_removed = vector_remove_unordered (vector, value_to_remove);
+
+ EXPECT_EQ (vector_len (vector), N_ELEMENTS - 1);
+ EXPECT_EQ (num_removed, 1);
+ for (size_t i = 0; i < vector_len (vector); i++)
+ EXPECT_NE (vector_at (vector, i), value_to_remove);
+}
+
+TEST_F (VectorTest, RemoveNonExistingElement)
+{
+ // Push some initial values
+ vector_push (vector, 1);
+ vector_push (vector, 2);
+ vector_push (vector, 3);
+ EXPECT_EQ (vector_len (vector), size_t (3));
+
+ // Remove non-existing element
+ int num_removed = vector_remove_unordered (vector, 5);
+ EXPECT_EQ (num_removed, 0);
+ size_t prev_size = vector_len (vector);
+ EXPECT_EQ (prev_size, vector_len (vector)) << "Size should not have changed";
+}
+
+TEST_F (VectorTest, RemoveDuplicatedElement)
+{
+ // Populate vector
+ for (size_t i = 0; i < N_ELEMENTS; i++)
+ vector_push (vector, i);
+ EXPECT_EQ (vector_len (vector), N_ELEMENTS);
+ for (size_t i = 0; i < vector_len (vector); i++)
+ EXPECT_EQ (vector_at (vector, i), (int) i);
+ vector_set (vector, 0, 3); // Duplicate element
+
+ // Remove (duplicated) elements
+ int value_to_remove = 3;
+ int num_removed = vector_remove_unordered (vector, value_to_remove);
+
+ EXPECT_EQ (vector_len (vector), N_ELEMENTS - 2);
+ EXPECT_EQ (num_removed, 2);
+ for (size_t i = 0; i < vector_len (vector); i++)
+ EXPECT_NE (vector_at (vector, i), value_to_remove);
+}
+
+TEST_F (VectorTest, Iterate)
+{
+ for (size_t i = 0; i < N_ELEMENTS; i++)
+ vector_push (vector, i);
+
+ int count = 0;
+ int *elem;
+ vector_foreach (vector, elem, { EXPECT_EQ (*elem, count++); });
+}
+
+TEST_F (VectorTest, MultipleResize)
+{
+ // Use small vector (size=1) to force multiple realloc operations
+ int *small_vector;
+ vector_init (small_vector, 1, 0);
+
+ for (size_t i = 0; i < N_ELEMENTS; i++)
+ vector_push (small_vector, i);
+
+ for (size_t i = 0; i < N_ELEMENTS; i++)
+ EXPECT_EQ (vector_at (small_vector, i), (int) i);
+
+ EXPECT_EQ (vector_len (small_vector), 5UL);
+ EXPECT_EQ (vector_get_alloc_size (small_vector), 8UL);
+
+ vector_free (small_vector);
+}
+
+TEST_F (VectorTest, MaxSize)
+{
+ const int max_size = 4;
+
+ // Fill the vector until max size is reached
+ int *small_vector;
+ vector_init (small_vector, 2, max_size);
+ for (int i = 0; i < max_size; i++)
+ vector_push (small_vector, i);
+
+ // Try expanding or appending elements should fail
+ int rc = vector_ensure_pos (small_vector, max_size);
+ EXPECT_EQ (rc, -1);
+ rc = vector_push (small_vector, 123);
+ EXPECT_EQ (rc, -1);
+
+ vector_free (small_vector);
+}
+
+TEST_F (VectorTest, Contains)
+{
+ // No elements
+ EXPECT_EQ (vector_contains (vector, 1), false);
+
+ // Push one element
+ vector_push (vector, 1);
+ EXPECT_EQ (vector_contains (vector, 1), true);
+
+ // Update element
+ vector_set (vector, 0, 2);
+ EXPECT_EQ (vector_contains (vector, 1), false);
+ EXPECT_EQ (vector_contains (vector, 2), true);
+}
+
+TEST_F (VectorTest, Remove)
+{
+ // Remove element at invalid position
+ int rc = vector_remove_at (vector, 2);
+ EXPECT_EQ (rc, -1); // Failure
+
+ // Push two elements and remove the second one
+ vector_push (vector, 1);
+ vector_push (vector, 2);
+ rc = vector_remove_at (vector, 1);
+ EXPECT_EQ (rc, 0); // Success
+ EXPECT_EQ (vector_len (vector), size_t (1));
+
+ // Push another element: it should replace the previous one
+ vector_push (vector, 3);
+ EXPECT_EQ (vector_len (vector), size_t (2));
+ EXPECT_EQ (vector_at (vector, 1), 3);
+}
+
+TEST_F (VectorTest, RemoveInTheMiddle)
+{
+ for (size_t i = 0; i < N_ELEMENTS; i++)
+ vector_push (vector, i);
+
+ // Remove element in central position
+ int rc = vector_remove_at (vector, 2);
+ EXPECT_EQ (rc, 0); // Success
+ EXPECT_EQ (vector_contains (vector, 2), false);
+ EXPECT_EQ (vector_len (vector), N_ELEMENTS - 1);
+
+ // Check if elements have been shifted (preserving the order)
+ int expected[] = { 0, 1, 3, 4 };
+ for (size_t i = 0; i < vector_len (vector); i++)
+ EXPECT_EQ (vector_at (vector, i), expected[i]);
+}
+
+TEST_F (VectorTest, Reset)
+{
+ vector_push (vector, 1);
+ vector_push (vector, 2);
+ EXPECT_EQ (vector_len (vector), size_t (2));
+
+ vector_reset (vector);
+ EXPECT_EQ (vector_len (vector), size_t (0));
+
+ vector_push (vector, 5);
+ EXPECT_EQ (vector_len (vector), size_t (1));
+ EXPECT_EQ (vector_contains (vector, 5), true);
+ EXPECT_EQ (vector_at (vector, 0), 5);
+} \ No newline at end of file
diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c
index 412baddcf..ba7c6475b 100644
--- a/lib/src/util/ip_address.c
+++ b/lib/src/util/ip_address.c
@@ -21,6 +21,7 @@
#include <hicn/util/ip_address.h>
#include <hicn/util/log.h>
#include <hicn/util/sstrncpy.h>
+#include <hicn/common.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#ifdef __ANDROID__
@@ -33,38 +34,44 @@
#endif
/* No htonl() with const */
-const ip_address_t IPV4_LOOPBACK = {
+const hicn_ip_address_t IPV4_LOOPBACK = {
.v4.as_inaddr.s_addr = SWAP (INADDR_LOOPBACK),
};
-const ip_address_t IPV6_LOOPBACK = {
+const hicn_ip_address_t IPV6_LOOPBACK = {
.v6.as_in6addr = IN6ADDR_LOOPBACK_INIT,
};
-const ip_address_t IPV4_ANY = {
+const hicn_ip_address_t IPV4_ANY = {
.v4.as_inaddr.s_addr = INADDR_ANY,
};
-const ip_address_t IPV6_ANY = {
+const hicn_ip_address_t IPV6_ANY = {
.v6.as_in6addr = IN6ADDR_ANY_INIT,
};
-const ip4_address_t IP4_ADDRESS_EMPTY = {
+const ipv4_address_t IP4_ADDRESS_EMPTY = {
.as_u32 = 0,
};
-const ip6_address_t IP6_ADDRESS_EMPTY = {
+const ipv6_address_t IP6_ADDRESS_EMPTY = {
.as_u64 = { 0, 0 },
};
-const ip_address_t IP_ADDRESS_EMPTY = {
+const hicn_ip_address_t IP_ADDRESS_EMPTY = {
.v6.as_u64 = { 0, 0 },
};
/* IP address */
int
-ip_address_get_family (const char *ip_address)
+hicn_ip_address_get_family (const hicn_ip_address_t *address)
+{
+ return hicn_ip_address_is_v4 (address) ? AF_INET : AF_INET6;
+}
+
+int
+hicn_ip_address_str_get_family (const char *ip_address)
{
struct addrinfo hint, *res = NULL;
int rc;
@@ -85,7 +92,7 @@ ip_address_get_family (const char *ip_address)
}
int
-ip_address_len (int family)
+hicn_ip_address_len (int family)
{
return (family == AF_INET6) ? IPV6_ADDR_LEN :
(family == AF_INET) ? IPV4_ADDR_LEN :
@@ -93,8 +100,20 @@ ip_address_len (int family)
}
int
-ip_address_ntop (const ip_address_t *ip_address, char *dst, const size_t len,
- int family)
+hicn_ip_address_get_len (const hicn_ip_address_t *ip_address)
+{
+ return hicn_ip_address_len (hicn_ip_address_get_family (ip_address));
+}
+
+int
+hicn_ip_address_get_len_bits (const hicn_ip_address_t *ip_address)
+{
+ return bytes_to_bits (hicn_ip_address_get_len (ip_address));
+}
+
+int
+hicn_ip_address_ntop (const hicn_ip_address_t *ip_address, char *dst,
+ const size_t len, int family)
{
const char *s;
switch (family)
@@ -115,12 +134,13 @@ ip_address_ntop (const ip_address_t *ip_address, char *dst, const size_t len,
* Parse ip addresses in presentation format
*/
int
-ip_address_pton (const char *ip_address_str, ip_address_t *ip_address)
+hicn_ip_address_pton (const char *hicn_ip_address_str,
+ hicn_ip_address_t *ip_address)
{
int pton_fd;
int family;
- family = ip_address_get_family (ip_address_str);
+ family = hicn_ip_address_str_get_family (hicn_ip_address_str);
switch (family)
{
@@ -128,10 +148,12 @@ ip_address_pton (const char *ip_address_str, ip_address_t *ip_address)
ip_address->pad[0] = 0;
ip_address->pad[1] = 0;
ip_address->pad[2] = 0;
- pton_fd = inet_pton (AF_INET, ip_address_str, &ip_address->v4.buffer);
+ pton_fd =
+ inet_pton (AF_INET, hicn_ip_address_str, &ip_address->v4.buffer);
break;
case AF_INET6:
- pton_fd = inet_pton (AF_INET6, ip_address_str, &ip_address->v6.buffer);
+ pton_fd =
+ inet_pton (AF_INET6, hicn_ip_address_str, &ip_address->v6.buffer);
break;
default:
return -1;
@@ -146,11 +168,11 @@ ip_address_pton (const char *ip_address_str, ip_address_t *ip_address)
}
int
-ip_address_snprintf (char *s, size_t size, const ip_address_t *ip_address,
- int family)
+hicn_ip_address_snprintf (char *s, size_t size,
+ const hicn_ip_address_t *ip_address)
{
-
const char *rc;
+ int family = hicn_ip_address_get_family (ip_address);
switch (family)
{
case AF_INET:
@@ -172,8 +194,8 @@ ip_address_snprintf (char *s, size_t size, const ip_address_t *ip_address,
}
int
-ip_address_to_sockaddr (const ip_address_t *ip_address, struct sockaddr *sa,
- int family)
+hicn_ip_address_to_sockaddr (const hicn_ip_address_t *ip_address,
+ struct sockaddr *sa, int family)
{
struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *) sa;
struct sockaddr_in *tmp4 = (struct sockaddr_in *) sa;
@@ -199,64 +221,66 @@ ip_address_to_sockaddr (const ip_address_t *ip_address, struct sockaddr *sa,
}
int
-ip_address_cmp (const ip_address_t *ip1, const ip_address_t *ip2, int family)
+hicn_ip_address_cmp (const hicn_ip_address_t *ip1,
+ const hicn_ip_address_t *ip2)
{
- switch (family)
- {
- case AF_INET:
- return memcmp (ip1->v4.buffer, ip2->v4.buffer, sizeof (ip1->v4));
- case AF_INET6:
- default:
- return memcmp (ip1->v6.buffer, ip2->v6.buffer, sizeof (ip1->v6));
- }
+ /* This works as soon as all members are initialized */
+ return memcmp (ip1, ip2, sizeof (hicn_ip_address_t));
+}
+
+bool
+hicn_ip_address_equals (const hicn_ip_address_t *ip1,
+ const hicn_ip_address_t *ip2)
+{
+ return hicn_ip_address_cmp (ip1, ip2) == 0;
}
int
-ip_address_empty (const ip_address_t *ip)
+hicn_ip_address_empty (const hicn_ip_address_t *ip)
{
- return (memcmp (ip->v6.buffer, &IP_ADDRESS_EMPTY.v6.buffer,
- sizeof (IP_ADDRESS_EMPTY)) == 0);
+ return (memcmp (ip, &IP_ADDRESS_EMPTY, sizeof (hicn_ip_address_t)) == 0);
}
/* Prefix */
/* Parse IP Prefixes in presentation format (in bits, separated by a slash) */
int
-ip_prefix_pton (const char *ip_address_str, ip_prefix_t *ip_prefix)
+hicn_ip_prefix_pton (const char *hicn_ip_address_str,
+ hicn_ip_prefix_t *hicn_ip_prefix)
{
int pton_fd;
char *p;
char *eptr;
- char *addr = strdup (ip_address_str);
+ char *addr = strdup (hicn_ip_address_str);
p = strchr (addr, '/');
if (!p)
{
- ip_prefix->len = ~0; // until we get the ip address family
+ hicn_ip_prefix->len = ~0; // until we get the ip address family
}
else
{
- ip_prefix->len = (u8) strtoul (p + 1, &eptr, 10);
+ hicn_ip_prefix->len = (u8) strtoul (p + 1, &eptr, 10);
*p = 0;
}
- ip_prefix->family = ip_address_get_family (addr);
+ hicn_ip_prefix->family = hicn_ip_address_str_get_family (addr);
- switch (ip_prefix->family)
+ switch (hicn_ip_prefix->family)
{
case AF_INET6:
- if (ip_prefix->len == (u8) ~0)
- ip_prefix->len = IPV6_ADDR_LEN_BITS;
- if (ip_prefix->len > IPV6_ADDR_LEN_BITS)
+ if (hicn_ip_prefix->len == (u8) ~0)
+ hicn_ip_prefix->len = IPV6_ADDR_LEN_BITS;
+ if (hicn_ip_prefix->len > IPV6_ADDR_LEN_BITS)
goto ERR;
- pton_fd = inet_pton (AF_INET6, addr, &ip_prefix->address.v6.buffer);
+ pton_fd = inet_pton (AF_INET6, addr, &hicn_ip_prefix->address.v6.buffer);
break;
case AF_INET:
- if (ip_prefix->len == (u8) ~0)
- ip_prefix->len = IPV4_ADDR_LEN_BITS;
- if (ip_prefix->len > IPV4_ADDR_LEN_BITS)
+ if (hicn_ip_prefix->len == (u8) ~0)
+ hicn_ip_prefix->len = IPV4_ADDR_LEN_BITS;
+ if (hicn_ip_prefix->len > IPV4_ADDR_LEN_BITS)
goto ERR;
- pton_fd = inet_pton (AF_INET, addr, &ip_prefix->address.v4.buffer);
+ pton_fd = inet_pton (AF_INET, addr, &hicn_ip_prefix->address.v4.buffer);
break;
default:
goto ERR;
@@ -275,18 +299,19 @@ ERR:
}
int
-ip_prefix_ntop_short (const ip_prefix_t *ip_prefix, char *dst, size_t size)
+hicn_ip_prefix_ntop_short (const hicn_ip_prefix_t *hicn_ip_prefix, char *dst,
+ size_t size)
{
char ip_s[MAXSZ_IP_ADDRESS];
const char *s;
- switch (ip_prefix->family)
+ switch (hicn_ip_prefix->family)
{
case AF_INET:
- s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s,
+ s = inet_ntop (AF_INET, hicn_ip_prefix->address.v4.buffer, ip_s,
MAXSZ_IP_ADDRESS);
break;
case AF_INET6:
- s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s,
+ s = inet_ntop (AF_INET6, hicn_ip_prefix->address.v6.buffer, ip_s,
MAXSZ_IP_ADDRESS);
break;
default:
@@ -301,18 +326,19 @@ ip_prefix_ntop_short (const ip_prefix_t *ip_prefix, char *dst, size_t size)
}
int
-ip_prefix_ntop (const ip_prefix_t *ip_prefix, char *dst, size_t size)
+hicn_ip_prefix_ntop (const hicn_ip_prefix_t *hicn_ip_prefix, char *dst,
+ size_t size)
{
char ip_s[MAXSZ_IP_ADDRESS];
const char *s;
- switch (ip_prefix->family)
+ switch (hicn_ip_prefix->family)
{
case AF_INET:
- s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s,
+ s = inet_ntop (AF_INET, hicn_ip_prefix->address.v4.buffer, ip_s,
MAXSZ_IP_ADDRESS);
break;
case AF_INET6:
- s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s,
+ s = inet_ntop (AF_INET6, hicn_ip_prefix->address.v6.buffer, ip_s,
MAXSZ_IP_ADDRESS);
break;
default:
@@ -320,26 +346,26 @@ ip_prefix_ntop (const ip_prefix_t *ip_prefix, char *dst, size_t size)
}
if (!s)
return -1;
- int rc = snprintf (dst, size, "%s/%d", ip_s, ip_prefix->len);
+ int rc = snprintf (dst, size, "%s/%d", ip_s, hicn_ip_prefix->len);
if (rc >= size)
return (int) size;
return rc;
}
int
-ip_prefix_snprintf (char *s, size_t size, const ip_prefix_t *prefix)
+hicn_ip_prefix_snprintf (char *s, size_t size, const hicn_ip_prefix_t *prefix)
{
- return ip_prefix_ntop (prefix, s, size);
+ return hicn_ip_prefix_ntop (prefix, s, size);
}
int
-ip_prefix_len (const ip_prefix_t *prefix)
+hicn_ip_prefix_len (const hicn_ip_prefix_t *prefix)
{
- return prefix->len; // ip_address_len(&prefix->address, prefix->family);
+ return prefix->len; // hicn_ip_address_len(&prefix->address, prefix->family);
}
const u8 *
-ip_address_get_buffer (const ip_address_t *ip_address, int family)
+hicn_ip_address_get_buffer (const hicn_ip_address_t *ip_address, int family)
{
switch (family)
{
@@ -353,20 +379,22 @@ ip_address_get_buffer (const ip_address_t *ip_address, int family)
}
bool
-ip_prefix_empty (const ip_prefix_t *prefix)
+hicn_ip_prefix_empty (const hicn_ip_prefix_t *prefix)
{
return prefix->len == 0;
}
int
-ip_prefix_to_sockaddr (const ip_prefix_t *prefix, struct sockaddr *sa)
+hicn_ip_prefix_to_sockaddr (const hicn_ip_prefix_t *prefix,
+ struct sockaddr *sa)
{
- // XXX assert len == ip_address_len
- return ip_address_to_sockaddr (&prefix->address, sa, prefix->family);
+ // XXX assert len == hicn_ip_address_len
+ return hicn_ip_address_to_sockaddr (&prefix->address, sa, prefix->family);
}
int
-ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2)
+hicn_ip_prefix_cmp (const hicn_ip_prefix_t *prefix1,
+ const hicn_ip_prefix_t *prefix2)
{
if (prefix1->family < prefix2->family)
return -1;
@@ -378,8 +406,26 @@ ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2)
else if (prefix1->len > prefix2->len)
return 1;
- return ip_address_cmp (&prefix1->address, &prefix2->address,
- prefix1->family);
+ return hicn_ip_address_cmp (&prefix1->address, &prefix2->address);
+}
+
+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);
+}
+
+bool
+hicn_ip_address_match_family (const hicn_ip_address_t *address, int family)
+{
+ return hicn_ip_address_get_family (address) == family;
+}
+
+uint32_t
+hicn_ip_address_get_hash (const hicn_ip_address_t *address)
+{
+ return hash32 (address, sizeof (address));
}
/* URL */
@@ -395,23 +441,27 @@ ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2)
#define MAXSZ_URL MAXSZ_URL_ + NULLTERM
int
-url_snprintf (char *s, size_t size, int family, const ip_address_t *ip_address,
+url_snprintf (char *s, size_t size, const hicn_ip_address_t *ip_address,
u16 port)
{
- char ip_address_s[MAXSZ_IP_ADDRESS];
+ char hicn_ip_address_s[MAXSZ_IP_ADDRESS];
int rc;
+ int family = hicn_ip_address_get_family (ip_address);
+
/* Other address are currently not supported */
if (!IS_VALID_FAMILY (family))
return -1;
+ if (!hicn_ip_address_match_family (ip_address, family))
+ return -1;
rc =
- ip_address_snprintf (ip_address_s, MAXSZ_IP_ADDRESS, ip_address, family);
+ hicn_ip_address_snprintf (hicn_ip_address_s, MAXSZ_IP_ADDRESS, ip_address);
if (rc >= MAXSZ_IP_ADDRESS)
WARN ("[url_snprintf] Unexpected ip_address truncation");
if (rc < 0)
return rc;
return snprintf (s, size, "inet%c://%s:%d", (family == AF_INET) ? '4' : '6',
- ip_address_s, port);
+ hicn_ip_address_s, port);
}
diff --git a/lib/src/util/pool.c b/lib/src/util/pool.c
index c6be92ce8..2c1e90b5e 100644
--- a/lib/src/util/pool.c
+++ b/lib/src/util/pool.c
@@ -28,6 +28,7 @@
#include <stdlib.h> // calloc
#include <hicn/util/pool.h>
+#include <hicn/util/log.h>
#include <stdio.h> // XXX
diff --git a/lib/src/util/types.c b/lib/src/util/types.c
new file mode 100644
index 000000000..744192593
--- /dev/null
+++ b/lib/src/util/types.c
@@ -0,0 +1,56 @@
+/*
+ * 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 <hicn/util/types.h>
+
+uint32_t
+htonf (float f)
+{
+ uint32_t i;
+ uint32_t sign = 0;
+
+ if (f < 0)
+ {
+ sign = 1;
+ f = -f;
+ }
+
+ // i[31] = sign bit
+ i = sign << 31;
+
+ // i[30 to 16] = int(f)[14 to 0]
+ i |= (((uint32_t) f) & 0x7fff) << 16;
+
+ // i[15 to 0] = fraction(f) bits [15 to 0]
+ i |= (uint32_t) ((f - (uint32_t) f) * 65536.0f) & 0xffff;
+
+ return i;
+}
+
+float
+ntohf (uint32_t i)
+{
+ // integer part = i[14 to 0]
+ float f = (i >> 16) & 0x7fff;
+
+ // fraction part = i[15 to 0]
+ f += (i & 0xffff) / 65536.0f;
+
+ // sign = i[31]
+ if ((i >> 31) & 1)
+ f = -f;
+
+ return f;
+}