aboutsummaryrefslogtreecommitdiffstats
path: root/lib/src
diff options
context:
space:
mode:
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;
+}