summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/includes/CMakeLists.txt19
-rw-r--r--lib/includes/hicn/base.h270
-rw-r--r--lib/includes/hicn/common.h94
-rw-r--r--lib/includes/hicn/compat.h529
-rw-r--r--lib/includes/hicn/error.h4
-rw-r--r--lib/includes/hicn/face.h26
-rw-r--r--lib/includes/hicn/header.h148
-rw-r--r--lib/includes/hicn/hicn.h29
-rw-r--r--lib/includes/hicn/interest_manifest.h105
-rw-r--r--lib/includes/hicn/mapme.h50
-rw-r--r--lib/includes/hicn/name.h129
-rw-r--r--lib/includes/hicn/ops.h1029
-rw-r--r--lib/includes/hicn/packet.h697
-rw-r--r--lib/includes/hicn/policy.h2
-rw-r--r--lib/includes/hicn/protocol/icmprd.h6
-rw-r--r--lib/includes/hicn/protocol/ipv4.h8
-rw-r--r--lib/includes/hicn/protocol/ipv6.h8
-rw-r--r--lib/includes/hicn/protocol/new.h2
-rw-r--r--lib/includes/hicn/util/bitmap.h150
-rw-r--r--lib/includes/hicn/util/hash.h1
-rw-r--r--lib/includes/hicn/util/ip_address.h146
-rw-r--r--lib/includes/hicn/util/pool.h28
-rw-r--r--lib/includes/hicn/util/sstrncpy.h7
-rw-r--r--lib/includes/hicn/util/types.h44
-rw-r--r--lib/includes/hicn/util/vector.h8
-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.h (renamed from lib/includes/hicn/protocol.h)13
-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
63 files changed, 7350 insertions, 4698 deletions
diff --git a/lib/includes/CMakeLists.txt b/lib/includes/CMakeLists.txt
index 392c2c94e..61af7eca8 100644
--- a/lib/includes/CMakeLists.txt
+++ b/lib/includes/CMakeLists.txt
@@ -24,29 +24,19 @@ set(LIBHICN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/hicn/hicn.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/base.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/common.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/compat.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/error.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/face.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/header.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/mapme.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/name.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/packet.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/policy.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ops.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/strategy.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/validation.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/interest_manifest.h
PARENT_SCOPE
)
-set(LIBHICN_HEADER_FILES_PROTOCOL
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/ah.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/icmp.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/icmprd.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/ipv4.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/ipv6.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/tcp.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/udp.h
- ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/new.h
+set(LIBHICN_HEADER_FILES_UTIL
${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/array.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/bitmap.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/hash.h
@@ -63,3 +53,6 @@ set(LIBHICN_HEADER_FILES_PROTOCOL
${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/vector.h
PARENT_SCOPE
)
+
+set_property(GLOBAL PROPERTY LIBHICN_HEADER_FILES_UTIL_PROPERTY "${LIBHICN_HEADER_FILES_UTIL}")
+
diff --git a/lib/includes/hicn/base.h b/lib/includes/hicn/base.h
index b825619b7..0a6ac7321 100644
--- a/lib/includes/hicn/base.h
+++ b/lib/includes/hicn/base.h
@@ -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:
@@ -32,8 +32,16 @@
/* Default header fields */
#define HICN_DEFAULT_TTL 254
+#define SYMBOLIC_NAME_LEN 16
+
+/* hICN attribute types */
+
+/* Face id */
+
typedef u32 hicn_faceid_t;
-typedef u8 hicn_pathlabel_t;
+
+/* Lifetime */
+
typedef u32 hicn_lifetime_t;
#define HICN_MAX_LIFETIME_SCALED 0xFFFF
@@ -56,6 +64,9 @@ typedef u32 hicn_lifetime_t;
* currently used by an hypothetical signed MAP-Me update :
* [IPPROTO_ICMPRD, IPPROTO_AH, IPPROTO_ICMP, IPPROTO_IPV6]
*/
+
+#define HICN_FORMAT_LEN 4
+
typedef union
{
/** protocol layers representation */
@@ -82,82 +93,166 @@ typedef union
};
/** u32 representation */
u32 as_u32;
-} hicn_type_t;
+ u8 as_u8[HICN_FORMAT_LEN];
+} hicn_packet_format_t;
/* Common protocol layers */
/* Common protocol layers */
#ifndef _WIN32
-#define HICN_TYPE(x, y, z, t) \
- (hicn_type_t) \
+#define HICN_PACKET_FORMAT(x, y, z, t) \
+ (hicn_packet_format_t) \
{ \
{ \
.l1 = x, .l2 = y, .l3 = z, .l4 = t \
} \
}
#else
-inline hicn_type_t
-HICN_TYPE (int x, int y, int z, int t)
+inline const hicn_packet_format_t
+HICN_PACKET_FORMAT (int x, int y, int z, int t)
{
- hicn_type_t type;
- type.l1 = x;
- type.l2 = y;
- type.l3 = z;
- type.l4 = t;
- return type;
+ hicn_packet_format_t format;
+ format.l1 = x;
+ format.l2 = y;
+ format.l3 = z;
+ format.l4 = t;
+ return format;
}
#endif
-#define HICN_TYPE_IPV4_TCP \
- HICN_TYPE (IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_ICMP \
- HICN_TYPE (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_TCP \
- HICN_TYPE (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_ICMP \
- HICN_TYPE (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_NEW \
- HICN_TYPE (IPPROTO_ENCAP, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_UDP \
- HICN_TYPE (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_UDP \
- HICN_TYPE (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_TCP_AH \
- HICN_TYPE (IPPROTO_IP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_IPV4_ICMP_AH \
- HICN_TYPE (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_TCP_AH \
- HICN_TYPE (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_ICMP_AH \
- HICN_TYPE (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE)
-#define HICN_TYPE_NEW_AH \
- HICN_TYPE (IPPROTO_ENCAP, IPPROTO_AH, IPPROTO_NONE, IPPROTO_NONE)
-#define HICN_TYPE_IPV6_UDP_AH \
- HICN_TYPE (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH)
-#define HICN_TYPE_IPV4_UDP_AH \
- HICN_TYPE (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH)
-#define HICN_TYPE_NONE \
- HICN_TYPE (IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
+extern const char *const _protocol_str[];
+
+#define protocol_str(x) protocol_str[x]
+
+int hicn_packet_format_snprintf (char *s, size_t size,
+ hicn_packet_format_t format);
+
+#define MAXSZ_HICN_PACKET_FORMAT 4 * 4 + 3 // ICMP/ICMP/ICMP/ICMP
+
+#if !defined(__cplusplus)
+#define constexpr const
+#endif
+
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_TCP =
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_ICMP =
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_TCP =
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_ICMP =
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE,
+ IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_NEW =
+ HICN_PACKET_FORMAT (IPPROTO_ENCAP, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_UDP =
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_UDP =
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_TCP_AH =
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_ICMP_AH =
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_AH, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_TCP_AH =
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_ICMP_AH =
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_NEW_AH =
+ HICN_PACKET_FORMAT (IPPROTO_ENCAP, IPPROTO_AH, IPPROTO_NONE, IPPROTO_NONE);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_UDP_AH =
+ HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_UDP_AH =
+ HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH);
+static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_NONE =
+ HICN_PACKET_FORMAT (IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE);
+
+/**
+ * @brief Return the hICN format with an additional AH header
+ * @param [in] format - hICN packet format
+ * @return Updated hICN packet format
+ */
+static inline hicn_packet_format_t
+hicn_get_ah_format (hicn_packet_format_t format)
+{
+ hicn_packet_format_t ret = format;
+ for (unsigned i = 0; i < HICN_FORMAT_LEN; i++)
+ {
+ switch (ret.as_u8[i])
+ {
+ case IPPROTO_AH:
+ return ret;
+ case IPPROTO_NONE:
+ ret.as_u8[i] = IPPROTO_AH;
+ return ret;
+ default:
+ break;
+ }
+ }
+ return ret;
+}
+
+/*
+ * MAX(IPV4_HDRLEN (20), IPV6_HDRLEN (40))
+ * + MAX (TCP_HDRLEN (20), UDP_HDRLEN (8), ICMP_HDRLEN (8), NEW_HDRLEN (32))
+ * + AH_HDRLEN
+ */
+#define HICN_HDRLEN_MAX 72
/**
* @brief Check if type is none.
* @return 1 if none, 0 otherwise
*/
static inline int
-hicn_type_is_none (hicn_type_t type)
+hicn_type_is_none (hicn_packet_format_t format)
{
- return (type.l1 == IPPROTO_NONE) && (type.l2 == IPPROTO_NONE) &&
- (type.l3 == IPPROTO_NONE) && (type.l4 == IPPROTO_NONE);
+ return (format.l1 == IPPROTO_NONE) && (format.l2 == IPPROTO_NONE) &&
+ (format.l3 == IPPROTO_NONE) && (format.l4 == IPPROTO_NONE);
}
+#define _is_ipv4(format) (format.l1 == IPPROTO_IP)
+#define _is_ipv6(format) (format.l1 == IPPROTO_IPV6)
+#define _is_tcp(format) (format.l2 == IPPROTO_TCP)
+#define _is_udp(format) (format.l2 == IPPROTO_UDP)
+#define _is_icmp(format) \
+ ((format.l2 == IPPROTO_ICMP) || (format.l2 == IPPROTO_ICMPV6))
+#define _is_cmpr(format) ((format & HFO_CMPR) >> 5)
+#define _is_ah(format) \
+ ((format.l1 == IPPROTO_AH) || (format.l2 == IPPROTO_AH) || \
+ (format.l3 == IPPROTO_AH))
+
+/*
+ * @brief hICN packet types
+ *
+ * probes are like normal interest & data but:
+ * - interests use BFD port as the destination
+ * - data use BFD port as the source + expiry time must be 0.
+ * if any of these conditions is not met, the packet is still matched as an
+ * interest or data packet.
+ *
+ */
+
+#define foreach_packet_type \
+ _ (UNDEFINED) \
+ _ (INTEREST) \
+ _ (DATA) \
+ _ (WLDR_NOTIFICATION) \
+ _ (MAPME) \
+ _ (PROBE) \
+ _ (COMMAND) \
+ _ (N)
+
/**
* @brief hICN Packet type
*/
typedef enum
{
- HICN_PACKET_TYPE_INTEREST,
- HICN_PACKET_TYPE_DATA,
- HICN_PACKET_N_TYPE,
+#define _(x) HICN_PACKET_TYPE_##x,
+ foreach_packet_type
+#undef _
} hicn_packet_type_t;
+#undef foreach_type
+
+extern const char *_hicn_packet_type_str[];
+
+#define hicn_packet_type_str(x) _hicn_packet_type_str[x]
/**
* @brief hICN Payload type
@@ -172,60 +267,11 @@ typedef enum
HPT_UNSPEC = 999
} hicn_payload_type_t;
-/***************************************************************
- * Interest Manifest
- ***************************************************************/
-
-#define MAX_SUFFIXES_IN_MANIFEST 255
-#define WORD_WIDTH (sizeof (uint32_t) * 8)
-#define BITMAP_SIZE ((MAX_SUFFIXES_IN_MANIFEST + 1) / WORD_WIDTH)
-
-typedef struct
-{
- /* This can be 16 bits, but we use 32 bits for alignment */
- uint32_t n_suffixes;
-
- uint32_t request_bitmap[BITMAP_SIZE];
-
- /* Followed by the list of prefixes to ask */
- /* ... */
-} interest_manifest_header_t;
-
-// Bitmap operations
-
-static inline void
-set_bit (uint32_t *bitmap, int i)
-{
- size_t offset = i / WORD_WIDTH;
- size_t pos = i % WORD_WIDTH;
- bitmap[offset] |= ((uint32_t) 1 << pos);
-}
-
-static inline void
-unset_bit (uint32_t *bitmap, int i)
-{
- size_t offset = i / WORD_WIDTH;
- size_t pos = i % WORD_WIDTH;
- bitmap[offset] &= ~((uint32_t) 1 << pos);
-}
+/* Path label */
-static inline bool
-is_bit_set (const uint32_t *bitmap, int i)
-{
- size_t offset = i / WORD_WIDTH;
- size_t pos = i % WORD_WIDTH;
- return bitmap[offset] & ((uint32_t) 1 << pos);
-}
+typedef u8 hicn_path_label_t;
-static inline void
-bitmap_print (u32 *bitmap, size_t n_words)
-{
- for (size_t word = 0; word < n_words; word++)
- {
- for (int bit = 31; bit >= 0; bit--)
- (is_bit_set (&bitmap[word], bit)) ? printf ("1") : printf ("0");
- }
-}
+#define INVALID_PATH_LABEL 0
/**
* @brief Path label computations
@@ -237,28 +283,28 @@ bitmap_print (u32 *bitmap, size_t n_words)
* NOTE: this computation is not (yet) part of the hICN specification.
*/
-#define HICN_PATH_LABEL_MASK 0x000000ff
-#define HICN_PATH_LABEL_SIZE 8
+#define HICN_PATH_LABEL_MASK 0x000000ff
+#define HICN_PATH_LABEL_SIZE_BITS sizeof (hicn_path_label_t) * 8
/**
* @brief Path label update
- * @param [in] current_label Current pathlabel
+ * @param [in] current_label Current path_label
* @param [in] face_id The face identifier to combine into the path label
- * @param [out] new_label Computed pathlabel
+ * @param [out] new_label Computed path_label
*
* This function updates the current_label based on the new face_id, and
* returns
*/
static inline void
-update_pathlabel (hicn_pathlabel_t current_label, hicn_faceid_t face_id,
- hicn_pathlabel_t *new_label)
+update_path_label (hicn_path_label_t current_label, hicn_faceid_t face_id,
+ hicn_path_label_t *new_label)
{
- hicn_pathlabel_t pl_face_id =
- (hicn_pathlabel_t) (face_id & HICN_PATH_LABEL_MASK);
+ hicn_path_label_t pl_face_id =
+ (hicn_path_label_t) (face_id & HICN_PATH_LABEL_MASK);
- *new_label =
- ((current_label << 1) | (current_label >> (HICN_PATH_LABEL_SIZE - 1))) ^
- pl_face_id;
+ *new_label = ((current_label << 1) |
+ (current_label >> (HICN_PATH_LABEL_SIZE_BITS - 1))) ^
+ pl_face_id;
}
/***************************************************************
diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h
index 1998099db..a84124617 100644
--- a/lib/includes/hicn/common.h
+++ b/lib/includes/hicn/common.h
@@ -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:
@@ -36,25 +36,11 @@
#include <stdint.h>
#include <assert.h>
-/* Concise type definitions */
+#include <hicn/util/types.h>
-typedef uint64_t u64;
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
-
-/*
- * Code annotations
- *
- * NOTE: these are defined by default in VPP.
- */
-
-#ifndef HICN_VPP_PLUGIN
-
-#define PREDICT_FALSE(x) (x)
-#define PREDICT_TRUE(x) (x)
-#define STRUCT_SIZE_OF(type, member) sizeof (((type *) 0)->member)
-#define ASSERT
+#define HICN_EXPECT_FALSE(x) __builtin_expect ((x), 1)
+#define HICN_EXPECT_TRUE(x) __builtin_expect ((x), 0)
+#define HICN_UNUSED(x) x __attribute__ ((unused))
#ifndef NDEBUG
#define _ASSERT(x) assert (x)
@@ -62,36 +48,6 @@ typedef uint8_t u8;
#define _ASSERT(x) ((void) (x))
#endif
-#define STATIC_ASSERT(x)
-
-/* Architecture-dependent uword size */
-#if INTPTR_MAX == INT64_MAX
-#define log2_uword_bits 6
-#elif INTPTR_MAX == INT32_MAX
-#define log2_uword_bits 5
-#else
-#error "Impossible to detect architecture"
-#endif
-
-#define uword_bits (1 << log2_uword_bits)
-
-/* Word types. */
-#if uword_bits == 64
-/* 64 bit word machines. */
-typedef u64 uword;
-#else
-/* 32 bit word machines. */
-typedef u32 uword;
-#endif
-
-typedef uword ip_csum_t;
-
-#else
-
-#include <vppinfra/clib.h>
-
-#endif /* ! HICN_VPP_PLUGIN */
-
/*
* Windows compilers do not support named initilizers when .h files are
* included inside C++ files. For readability, we either use the following
@@ -178,11 +134,11 @@ int get_addr_family (const char *ip_address);
*/
static inline u16
-ip_csum_fold (ip_csum_t c)
+ip_csum_fold (hicn_ip_csum_t c)
{
/* Reduce to 16 bits. */
#if uword_bits == 64
- c = (c & (ip_csum_t) 0xffffffff) + (c >> (ip_csum_t) 32);
+ c = (c & (hicn_ip_csum_t) 0xffffffff) + (c >> (hicn_ip_csum_t) 32);
c = (c & 0xffff) + (c >> 16);
#endif
@@ -192,18 +148,18 @@ ip_csum_fold (ip_csum_t c)
return (u16) c;
}
-static inline ip_csum_t
-ip_csum_with_carry (ip_csum_t sum, ip_csum_t x)
+static inline hicn_ip_csum_t
+ip_csum_with_carry (hicn_ip_csum_t sum, hicn_ip_csum_t x)
{
- ip_csum_t t = sum + x;
+ hicn_ip_csum_t t = sum + x;
return t + (t < x);
}
/* Update checksum changing field at even byte offset from x -> 0. */
-static inline ip_csum_t
-ip_csum_add_even (ip_csum_t c, ip_csum_t x)
+static inline hicn_ip_csum_t
+ip_csum_add_even (hicn_ip_csum_t c, hicn_ip_csum_t x)
{
- ip_csum_t d;
+ hicn_ip_csum_t d;
d = c - x;
@@ -214,8 +170,8 @@ ip_csum_add_even (ip_csum_t c, ip_csum_t x)
}
/* Update checksum changing field at even byte offset from 0 -> x. */
-static inline ip_csum_t
-ip_csum_sub_even (ip_csum_t c, ip_csum_t x)
+static inline hicn_ip_csum_t
+ip_csum_sub_even (hicn_ip_csum_t c, hicn_ip_csum_t x)
{
return ip_csum_with_carry (c, x);
}
@@ -265,8 +221,19 @@ csum (const void *addr, size_t size, u16 init)
* Query IP version from packet (either 4 or 6)
* (version is located as same offsets in both protocol headers)
*/
-#define HICN_IP_VERSION(packet) \
- ((hicn_header_t *) packet)->protocol.ipv4.version
+typedef struct
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ u8 dummy : 4;
+ u8 version : 4;
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ u8 version : 4;
+ u8 dummy : 4;
+#else
+#error "Unsupported endianness"
+#endif
+} ip_version_t;
+#define HICN_IP_VERSION(packet) ((ip_version_t *) packet)->version
#ifndef ntohll
static inline uint64_t
@@ -296,9 +263,9 @@ htonll (uint64_t input)
}
#endif
-#define round_pow2(x, pow2) (((x) + (pow2) -1) & ~((pow2) -1))
+#define hicn_round_pow2(x, pow2) (((x) + (pow2) -1) & ~((pow2) -1))
-#define _SIZEOF_ALIGNED(x, size) round_pow2 (sizeof (x), size)
+#define _SIZEOF_ALIGNED(x, size) hicn_round_pow2 (sizeof (x), size)
#define SIZEOF_ALIGNED(x) _SIZEOF_ALIGNED (x, sizeof (void *))
/* Definitions for builtins unavailable on MSVC */
@@ -336,6 +303,7 @@ uint32_t __inline __builtin_clzl2 (uint64_t value)
#endif
#define next_pow2(x) (x <= 1 ? 1 : 1ul << (64 - __builtin_clzl (x - 1)))
+#define _unused(x) ((void) (x))
#endif /* HICN_COMMON_H */
diff --git a/lib/includes/hicn/compat.h b/lib/includes/hicn/compat.h
deleted file mode 100644
index 98c035b57..000000000
--- a/lib/includes/hicn/compat.h
+++ /dev/null
@@ -1,529 +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.h
- * @brief Implementation of the compatibility layer.
- *
- * The structure of the core API has evolved to support operations of a variety
- * of packet formats in addition to IPv4/TCP and IPv6/TCP, namely with the use
- * of ICMP for signalization and AH headers for integrity. The new API format
- * has been designed to scale better with the multiplicity of packet formats,
- * and provide a unified interface on top. We maintain an interface for the
- * former API in this file, which mainly acts as a wrapper on top of new calls.
- */
-#ifndef HICN_COMPAT_H
-#define HICN_COMPAT_H
-
-#include "common.h"
-#include "header.h"
-#include "name.h"
-
-/* HICN format options */
-#define HFO_INET 1 << 0
-#define HFO_INET6 1 << 1
-#define HFO_TCP 1 << 2
-#define HFO_UDP 1 << 3
-#define HFO_ICMP 1 << 4
-#define HFO_CMPR 1 << 5
-#define HFO_AH 1 << 6
-
-#define _is_ipv4(format) ((format & HFO_INET))
-#define _is_ipv6(format) ((format & HFO_INET6) >> 1)
-#define _is_tcp(format) ((format & HFO_TCP) >> 2)
-#define _is_udp(format) ((format & HFO_UDP) >> 3)
-#define _is_icmp(format) ((format & HFO_ICMP) >> 4)
-#define _is_cmpr(format) ((format & HFO_CMPR) >> 5)
-#define _is_ah(format) ((format & HFO_AH) >> 6)
-
-typedef enum
-{
- HF_UNSPEC = 0,
- HF_INET_TCP = HFO_INET | HFO_TCP,
- HF_INET6_TCP = HFO_INET6 | HFO_TCP,
- HF_INET_ICMP = HFO_INET | HFO_ICMP,
- HF_INET6_ICMP = HFO_INET6 | HFO_ICMP,
- HF_NEW = HFO_CMPR,
- HF_INET_UDP = HFO_INET | HFO_UDP | HFO_CMPR,
- HF_INET6_UDP = HFO_INET6 | HFO_UDP | HFO_CMPR,
- HF_INET_TCP_AH = HFO_INET | HFO_TCP | HFO_AH,
- HF_INET6_TCP_AH = HFO_INET6 | HFO_TCP | HFO_AH,
- HF_INET_ICMP_AH = HFO_INET | HFO_ICMP | HFO_AH,
- HF_INET6_ICMP_AH = HFO_INET6 | HFO_ICMP | HFO_AH,
- HF_NEW_AH = HFO_CMPR | HFO_AH,
- HF_INET_UDP_AH = HFO_INET | HFO_UDP | HFO_CMPR | HFO_AH,
- HF_INET6_UDP_AH = HFO_INET6 | HFO_UDP | HFO_CMPR | HFO_AH,
-} hicn_format_t;
-
-/**
- * @brief Add AH header to current format. E.g. if format is IP + TCP, this
- * will change it to IP = TCP + AH
- *
- * @param [in] format - The input format
- * @return The format with the AH bit set to 1
- */
-static inline hicn_format_t
-hicn_get_ah_format (hicn_format_t format)
-{
- return (hicn_format_t) (format | HFO_AH);
-}
-
-/**
- * Minimum required header length to determine the type and length of a
- * supposed hICN packet. This should be equal to the maximum value over all
- * possible hICN packet formats, and less than the minimum possible IP packet
- * size.
- */
-#define HICN_V6_MIN_HDR_LEN 6 /* bytes */
-#define HICN_V4_MIN_HDR_LEN 4 /* bytes */
-
-// #define HICN_MIN_HDR_LEN ((HICN_V6_MIN_HDR_LEN > HICN_V4_MIN_HDR_LEN) ?
-// HICN_V6_MIN_HDR_LEN : HICN_V4_MIN_HDR_LEN)
-#define HICN_MIN_HDR_LEN HICN_V6_MIN_HDR_LEN
-
-hicn_type_t hicn_header_to_type (const hicn_header_t *h);
-
-/**
- * @brief Parse packet headers and return hICN format
- * @param [in] format - hICN Format
- * @param [in, out] packet - Buffer containing the hICN header to be
- * initialized
- * @return hICN error code
- */
-int hicn_packet_init_header (hicn_format_t format, hicn_header_t *packet);
-
-/**
- * @brief Parse packet headers and return hICN format
- * @param [in] h - hICN header
- * @param [out] format - hICN format
- * @return hICN error code
- */
-int hicn_packet_get_format (const hicn_header_t *packet,
- hicn_format_t *format);
-
-/**
- * @brief Update checksums in packet headers
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @return hICN error code
- */
-int hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t *packet);
-
-/**
- * @brief compute the checksum of the packet header, adding init_sum to the
- * final value
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @param [in] init_sum - value to add to the final checksum
- * @return hICN error code
- */
-int hicn_packet_compute_header_checksum (hicn_format_t format,
- hicn_header_t *packet, u16 init_sum);
-
-/**
- * @brief Verify checksums in packet headers
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @return hICN error code
- */
-int hicn_packet_check_integrity_no_payload (hicn_format_t format,
- hicn_header_t *packet,
- u16 init_sum);
-
-// this is not accounted here
-/**
- * @brief Return total length of hicn headers (but signature payload)
- * @param [in] format - hICN format
- * @param [out] header_length - Total length of headers
- * @return hICN error code
- */
-int hicn_packet_get_header_length_from_format (hicn_format_t format,
- size_t *header_length);
-
-/**
- * @brief Return total length of hicn headers (before payload)
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] header_length - Total length of headers
- * @return hICN error code
- */
-int hicn_packet_get_header_length (hicn_format_t format,
- const hicn_header_t *packet,
- size_t *header_length);
-
-/**
- * @brief Return payload length
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] payload_length - payload length
- * @return hICN error code
- */
-int hicn_packet_get_payload_length (hicn_format_t format,
- const hicn_header_t *packet,
- size_t *payload_length);
-
-/**
- * @brief Sets payload length
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @param [in] payload_length - payload length
- * @return hICN error code
- */
-int hicn_packet_set_payload_length (hicn_format_t format,
- hicn_header_t *packet,
- const size_t payload_length);
-
-/**
- * @brief Compare two hICN packets
- * @param [in] packet_1 - First packet
- * @param [in] packet_2 - Second packet
- * @return 0 if both packets are considered equal, any other value otherwise.
- */
-int hicn_packet_compare (const hicn_header_t *packet1,
- const hicn_header_t *packet2);
-
-/**
- * @brief Retrieve the name of an interest/data packet
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] name - name holding the result
- * @param [in] is_interest - Flag to determine whether it is an interest (1) or
- * data packet (0)
- * @return hICN error code
- */
-int hicn_packet_get_name (hicn_format_t format, const hicn_header_t *packet,
- hicn_name_t *name, u8 is_interest);
-
-/**
- * @brief Sets the name of an interest/data packet
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @param [in] name - name to set into packet
- * @param [in] is_interest - Flag to determine whether it is an interest (1) or
- * data packet (0)
- * @return hICN error code
- */
-int hicn_packet_set_name (hicn_format_t format, hicn_header_t *packet,
- const hicn_name_t *name, u8 is_interest);
-
-/**
- * @brief Sets the payload of a packet
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @param [in] payload - payload to set
- * @param [in] payload_length - size of the payload to set
- * @return hICN error code
- *
- * NOTE:
- * - The buffer holding payload is assumed sufficiently large
- * - This function updates header fields with the new length, but no checksum.
- */
-int hicn_packet_set_payload (hicn_format_t format, hicn_header_t *packet,
- const u8 *payload, u16 payload_length);
-
-/**
- * @brief Retrieves the payload of a packet
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] payload - pointer to buffer for storing the result
- * @param [out] payload_length - size of the retreived payload
- * @param [in] hard_copy - Flag : if true (eg. 1), a copy of the payload is
- * made into the payload buffer, otherwise (0) the pointer is changed to point
- * to the payload offset in the packet.
- * @return hICN error code
- *
- * NOTE:
- * - The buffer holding payload is assumed sufficiently large
- */
-int hicn_packet_get_payload (hicn_format_t format, const hicn_header_t *packet,
- u8 **payload, size_t *payload_size,
- bool hard_copy);
-
-/**
- * @brief Retrieve the locator of an interest / data packet
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] ip_address - retrieved locator
- * @param [in] is_interest - Flag to determine whether it is an interest (1) or
- * data packet (0)
- * @return hICN error code
- */
-int hicn_packet_get_locator (hicn_format_t format, const hicn_header_t *packet,
- ip_address_t *prefix, bool is_interest);
-
-/**
- * @brief Sets the locator of an interest / data packet
- * @param [in] format - hICN format
- * @param [in,out] packet - packet header
- * @param [out] ip_address - retrieved locator
- * @param [in] is_interest - Flag to determine whether it is an interest (1) or
- * data packet (0)
- * @return hICN error code
- */
-int hicn_packet_set_locator (hicn_format_t format, hicn_header_t *packet,
- const ip_address_t *prefix, bool is_interest);
-
-/**
- * @brief Retrieves the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] bytes - Retrieved signature size
- * @return hICN error code
- */
-int hicn_packet_get_signature_size (hicn_format_t format,
- const hicn_header_t *packet,
- size_t *bytes);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [in] bytes - Retrieved signature size
- * @return hICN error code
- */
-int hicn_packet_set_signature_size (hicn_format_t format,
- hicn_header_t *packet, size_t bytes);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [in] signature_timestamp - Signature timestamp to set
- * @return hICN error code
- */
-int hicn_packet_set_signature_timestamp (hicn_format_t format,
- hicn_header_t *h,
- uint64_t signature_timestamp);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] signature_timestamp - Retrieved signature timestamp
- * @return hICN error code
- */
-int hicn_packet_get_signature_timestamp (hicn_format_t format,
- const hicn_header_t *h,
- uint64_t *signature_timestamp);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [in] validation_algorithm - Validation algorithm to set
- * @return hICN error code
- */
-int hicn_packet_set_validation_algorithm (hicn_format_t format,
- hicn_header_t *h,
- uint8_t validation_algorithm);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] validation_algorithm - Retrieved validation algorithm
- * @return hICN error code
- */
-int hicn_packet_get_validation_algorithm (hicn_format_t format,
- const hicn_header_t *h,
- uint8_t *validation_algorithm);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [in] key_id - Key id to set
- * @return hICN error code
- */
-int hicn_packet_set_key_id (hicn_format_t format, hicn_header_t *h,
- uint8_t *key_id);
-
-/**
- * @brief Sets the signature size
- * @param [in] format - hICN format
- * @param [in] packet - packet header
- * @param [out] key_id - Retrieved key id
- * @return hICN error code
- */
-int hicn_packet_get_key_id (hicn_format_t format, hicn_header_t *h,
- uint8_t **key_id, uint8_t *key_id_length);
-
-/**
- * @brief Retrieves the packet hop limit
- * @param [in] packet - packet header
- * @param [out] hops - Retrieved hop limit
- * @return hICN error code
- */
-int hicn_packet_get_hoplimit (const hicn_header_t *packet, u8 *hops);
-
-/**
- * @brief Sets the packet hop limit
- * @param [in] packet - packet header
- * @param [in] hops - Hop limit to set
- * @return hICN error code
- */
-int hicn_packet_set_hoplimit (hicn_header_t *packet, u8 hops);
-
-/**
- * @brief Check if this packet is interest
- *
- * @param format - hICN format
- * @param packet - Packet header
- * @return hICN error code
- */
-int hicn_packet_is_interest (hicn_format_t format, const hicn_header_t *h,
- int *ret);
-
-/**
- * @brief Mark this packet as interest
- *
- * @param format - hICN format
- * @param packet - Packet header
- * @return hICN error code
- */
-int hicn_packet_set_interest (hicn_format_t format, hicn_header_t *packet);
-
-/**
- * @brief Mark this packet as data
- *
- * @param format - hICN format
- * @param packet - Packet header
- * @return hICN error code
- */
-int hicn_packet_set_data (hicn_format_t format, hicn_header_t *h);
-
-int hicn_packet_copy_header (hicn_format_t format, const hicn_header_t *packet,
- hicn_header_t *destination, bool copy_ah);
-
-int hicn_packet_get_lifetime (hicn_format_t format,
- const hicn_header_t *packet, u32 *lifetime);
-int hicn_packet_set_lifetime (hicn_format_t format, hicn_header_t *packet,
- u32 lifetime);
-int hicn_packet_get_reserved_bits (const hicn_header_t *packet,
- u8 *reserved_bits);
-int hicn_packet_set_reserved_bits (hicn_header_t *packet,
- const u8 reserved_bits);
-int hicn_packet_get_payload_type (hicn_format_t format,
- const hicn_header_t *packet,
- hicn_payload_type_t *payload_type);
-int hicn_packet_set_payload_type (hicn_format_t format, hicn_header_t *packet,
- const hicn_payload_type_t payload_type);
-
-int hicn_packet_set_syn (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_reset_syn (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_test_syn (hicn_format_t format, const hicn_header_t *packet,
- bool *flag);
-int hicn_packet_set_ack (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_reset_ack (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_test_ack (hicn_format_t format, const hicn_header_t *packet,
- bool *flag);
-int hicn_packet_set_rst (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_reset_rst (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_test_rst (hicn_format_t format, const hicn_header_t *packet,
- bool *flag);
-int hicn_packet_set_fin (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_reset_fin (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_test_fin (hicn_format_t format, const hicn_header_t *packet,
- bool *flag);
-int hicn_packet_set_ece (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_reset_ece (hicn_format_t format, hicn_header_t *packet);
-int hicn_packet_test_ece (hicn_format_t format, const hicn_header_t *packet,
- bool *flag);
-
-int hicn_packet_set_src_port (hicn_format_t format, hicn_header_t *packet,
- u16 src_port);
-int hicn_packet_get_src_port (hicn_format_t format,
- const hicn_header_t *packet, u16 *src_port);
-int hicn_packet_set_dst_port (hicn_format_t format, hicn_header_t *packet,
- u16 dst_port);
-int hicn_packet_get_dst_port (hicn_format_t format,
- const hicn_header_t *packet, u16 *dst_port);
-int hicn_packet_get_signature (hicn_format_t format, hicn_header_t *packet,
- uint8_t **sign_buf);
-
-/* Interest */
-int hicn_interest_get_name (hicn_format_t format,
- const hicn_header_t *interest, hicn_name_t *name);
-int hicn_interest_set_name (hicn_format_t format, hicn_header_t *interest,
- const hicn_name_t *name);
-int hicn_interest_get_locator (hicn_format_t format,
- const hicn_header_t *interest,
- ip_address_t *prefix);
-int hicn_interest_set_locator (hicn_format_t format, hicn_header_t *interest,
- const ip_address_t *prefix);
-int hicn_interest_compare (const hicn_header_t *interest_1,
- const hicn_header_t *interest_2);
-int hicn_interest_set_lifetime (hicn_header_t *interest, u32 lifetime);
-int hicn_interest_get_lifetime (const hicn_header_t *interest, u32 *lifetime);
-int hicn_interest_get_header_length (hicn_format_t format,
- const hicn_header_t *interest,
- size_t *header_length);
-int hicn_interest_get_payload_length (hicn_format_t format,
- const hicn_header_t *interest,
- size_t *payload_length);
-int hicn_interest_set_payload (hicn_format_t format, hicn_header_t *interest,
- const u8 *payload, size_t 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);
-int hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t *packet);
-
-/* Data */
-
-int hicn_data_get_name (hicn_format_t format, const hicn_header_t *data,
- hicn_name_t *name);
-int hicn_data_set_name (hicn_format_t format, hicn_header_t *data,
- const hicn_name_t *name);
-int hicn_data_get_locator (hicn_format_t format, const hicn_header_t *data,
- ip_address_t *prefix);
-int hicn_data_set_locator (hicn_format_t format, hicn_header_t *data,
- const ip_address_t *prefix);
-int hicn_data_compare (const hicn_header_t *data_1,
- const hicn_header_t *data_2);
-int hicn_data_get_expiry_time (const hicn_header_t *data, u32 *expiry_time);
-int hicn_data_set_expiry_time (hicn_header_t *data, u32 expiry_time);
-int hicn_data_get_header_length (hicn_format_t format, hicn_header_t *data,
- size_t *header_length);
-int hicn_data_get_payload_length (hicn_format_t format,
- const hicn_header_t *data,
- size_t *payload_length);
-int hicn_data_get_path_label (const hicn_header_t *data, u32 *path_label);
-int hicn_data_set_path_label (hicn_header_t *data, u32 path_label);
-int hicn_data_get_payload (hicn_format_t format, const hicn_header_t *data,
- u8 **payload, size_t *payload_size, bool hard_copy);
-int hicn_data_set_payload (hicn_format_t format, hicn_header_t *data,
- const u8 *payload, size_t payload_length);
-int hicn_data_get_payload_type (const hicn_header_t *data,
- hicn_payload_type_t *payload_type);
-int hicn_data_set_payload_type (hicn_header_t *data,
- hicn_payload_type_t payload_type);
-int hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t *packet);
-int hicn_data_is_last (hicn_format_t format, hicn_header_t *h, int *is_last);
-int hicn_data_set_last (hicn_format_t format, hicn_header_t *h);
-
-int hicn_packet_get_signature_padding (hicn_format_t format,
- const hicn_header_t *h, size_t *bytes);
-int hicn_packet_set_signature_padding (hicn_format_t format, hicn_header_t *h,
- size_t bytes);
-
-#endif /* HICN_COMPAT_H */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/lib/includes/hicn/error.h b/lib/includes/hicn/error.h
index d769ef693..9926c9cd8 100644
--- a/lib/includes/hicn/error.h
+++ b/lib/includes/hicn/error.h
@@ -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:
@@ -47,6 +47,8 @@ typedef enum
extern const char *HICN_LIB_ERROR_STRING[];
+#define HICN_LIB_IS_ERROR(rc) (rc < 0)
+
#define hicn_strerror(errno) (char *) (HICN_LIB_ERROR_STRING[-errno])
#endif /* HICN_ERROR_H */
diff --git a/lib/includes/hicn/face.h b/lib/includes/hicn/face.h
index 31906afab..fbdacec5f 100644
--- a/lib/includes/hicn/face.h
+++ b/lib/includes/hicn/face.h
@@ -37,6 +37,7 @@
/* Netdevice type */
#include <net/if.h> // IFNAMSIZ
+#include "base.h"
#define foreach_netdevice_type \
_ (UNDEFINED) \
@@ -58,10 +59,17 @@ typedef enum
#undef _
} netdevice_type_t;
+typedef uint32_t netdevice_flags_t;
+#define NETDEVICE_FLAGS_EMPTY 0
+#define netdevice_flags_clear(F) (F = 0)
+#define netdevice_flags_add(F, T) ((F) |= 1 << (T))
+#define netdevice_flags_remove(F, T) ((F) &= ~(1 << (T)))
+#define netdevice_flags_has(F, T) ((F) & (1 << (T)))
+
extern const char *_netdevice_type_str[];
#define netdevice_type_str(x) _netdevice_type_str[x]
-#define NETDEVICE_INVALID_INDEX ~0
+#define INVALID_NETDEVICE_ID ~0
/* Netdevice */
@@ -97,6 +105,7 @@ int netdevice_set_name (netdevice_t *netdevice, const char *name);
int netdevice_update_index (netdevice_t *netdevice);
int netdevice_update_name (netdevice_t *netdevice);
int netdevice_cmp (const netdevice_t *nd1, const netdevice_t *nd2);
+bool netdevice_is_empty (const netdevice_t *netdevice);
#define NETDEVICE_UNDEFINED_INDEX 0
@@ -175,9 +184,12 @@ face_type_t face_type_from_str (const char *str);
/* Face */
typedef u32 face_id_t;
+#define INVALID_FACE_ID ~0
typedef struct
{
+ face_id_t id;
+ char name[SYMBOLIC_NAME_LEN];
face_type_t type;
face_state_t admin_state;
face_state_t state;
@@ -191,16 +203,16 @@ typedef struct
*/
netdevice_t netdevice;
int family; /* To access family independently of face type */
- ip_address_t local_addr;
- ip_address_t remote_addr;
+ hicn_ip_address_t local_addr;
+ hicn_ip_address_t remote_addr;
u16 local_port;
u16 remote_port;
} face_t;
int 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);
int face_initialize_udp_sa (face_t *face, const char *interface_name,
const struct sockaddr *local_addr,
@@ -208,8 +220,8 @@ int face_initialize_udp_sa (face_t *face, const char *interface_name,
face_t *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,
+ 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_create_udp_sa (const char *interface_name,
const struct sockaddr *local_addr,
diff --git a/lib/includes/hicn/header.h b/lib/includes/hicn/header.h
deleted file mode 100644
index 208e35d68..000000000
--- a/lib/includes/hicn/header.h
+++ /dev/null
@@ -1,148 +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 header.h
- * @brief hICN header data structures.
- *
- * NOTE: These structures are used as convenient facade for accessing
- * the encapsulated headers. They are not written taking compiler padding
- * into account, then a sizeof() on these struct could not give the expected
- * result. For accessing the size of the hicn headers use the macros at the end
- * of this file.
- */
-
-#ifndef HICN_HEADER_H
-#define HICN_HEADER_H
-
-#include "common.h"
-#include "protocol.h"
-
-typedef struct
-{
- _ipv6_header_t ip;
- union
- {
- _tcp_header_t tcp;
- struct
- {
- _udp_header_t udp;
- _new_header_t newhdr;
- };
- _icmp_header_t icmp;
- _icmp_wldr_header_t wldr;
- };
-} hicn_v6_hdr_t;
-
-typedef struct
-{
- _ipv6_header_t ip;
- union
- {
- struct
- {
- _tcp_header_t tcp;
- _ah_header_t ah;
- };
- struct
- {
- _udp_header_t udp;
- _new_header_t newhdr;
- _ah_header_t udp_ah;
- };
- struct
- {
- _icmp_header_t icmp;
- _ah_header_t icmp_ah;
- };
- };
-} hicn_v6ah_hdr_t;
-
-// For ipv4 we need to use packed structs as fields may be aligned to 64 bits
-// (So for instance tcp header may start at byte #24 instead of byte 20)
-typedef PACKED (struct {
- _ipv4_header_t ip;
- union
- {
- _tcp_header_t tcp;
- struct
- {
- _udp_header_t udp;
- _new_header_t newhdr;
- };
- _icmp_header_t icmp;
- _icmp_wldr_header_t wldr;
- };
-}) hicn_v4_hdr_t;
-
-typedef PACKED (struct {
- _ipv4_header_t ip;
- union
- {
- struct
- {
- _tcp_header_t tcp;
- _ah_header_t ah;
- };
- struct
- {
- _udp_header_t udp;
- _new_header_t newhdr;
- _ah_header_t udp_ah;
- };
- struct
- {
- _icmp_header_t icmp;
- _ah_header_t icmp_ah;
- };
- };
-}) hicn_v4ah_hdr_t;
-
-typedef union
-{
- /* To deprecate as redundant with hicn_type_t */
- hicn_v6_hdr_t v6;
- hicn_v6ah_hdr_t v6ah;
- hicn_v4_hdr_t v4;
- hicn_v4ah_hdr_t v4ah;
-
- hicn_protocol_t protocol;
-} hicn_header_t;
-
-#define HICN_V6_TCP_HDRLEN (IPV6_HDRLEN + TCP_HDRLEN)
-#define HICN_V6_ICMP_HDRLEN (IPV6_HDRLEN + ICMP_HDRLEN)
-#define HICN_V6_WLDR_HDRLEN (IPV6_HDRLEN + ICMPWLDR_HDRLEN)
-
-#define HICN_V6_TCP_AH_HDRLEN (HICN_V6_TCP_HDRLEN + AH_HDRLEN)
-#define HICN_V6_ICMP_AH_HDRLEN (HICN_V6_ICMP_HDRLEN + AH_HDRLEN)
-
-#define HICN_V4_TCP_HDRLEN (IPV4_HDRLEN + TCP_HDRLEN)
-#define HICN_V4_ICMP_HDRLEN (IPV4_HDRLEN + ICMP_HDRLEN)
-#define HICN_V4_WLDR_HDRLEN (IPV4_HDRLEN + ICMPWLDR_HDRLEN)
-
-#define HICN_V4_TCP_AH_HDRLEN (HICN_V4_TCP_HDRLEN + AH_HDRLEN)
-#define HICN_V4_ICMP_AH_HDRLEN (HICN_V4_ICMP_HDRLEN + AH_HDRLEN)
-
-#define HICN_DEFAULT_PORT 9695
-
-#endif /* HICN_HEADER_H */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/lib/includes/hicn/hicn.h b/lib/includes/hicn/hicn.h
index 4a5b4dd56..5e67d83a0 100644
--- a/lib/includes/hicn/hicn.h
+++ b/lib/includes/hicn/hicn.h
@@ -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:
@@ -29,6 +29,14 @@
* Recovery (WLDR) [2], Anchorless Mobility Management (hICN-AMM) [3],
* including MAP-Me producer mobility mechanisms [4].
*
+ * Other hICN constructs such as faces, policies and stategies are not included
+ * in this header, but available separately in :
+ * - hicn/face.h
+ * - hicn/policy.h
+ * - hicn/strategy.h
+ *
+ * REFERENCES
+ *
* [1] Hybrid Information-Centric Networking
* L. Muscariello, G. Carofiglio, J. Augé, M. Papalini
* IETF draft (intarea) @
@@ -52,22 +60,21 @@
#ifndef HICN__H
#define HICN__H
-#ifdef HICN_VPP_PLUGIN
+/* Base data structures */
+#include <hicn/base.h>
-#include <hicn/header.h>
+/* Names */
#include <hicn/name.h>
-#include <hicn/ops.h>
-#include <hicn/mapme.h>
-#else
+/* Packet operations */
+#include <hicn/packet.h>
-#include <hicn/error.h>
-#include <hicn/header.h>
-#include <hicn/name.h>
-#include <hicn/ops.h>
+/* MAP-Me : mobility management operations */
#include <hicn/mapme.h>
-#include <hicn/compat.h>
+/* Error management */
+#ifndef HICN_VPP_PLUGIN
+#include <hicn/error.h>
#endif
#endif /* HICN__H */
diff --git a/lib/includes/hicn/interest_manifest.h b/lib/includes/hicn/interest_manifest.h
new file mode 100644
index 000000000..03f54d6d5
--- /dev/null
+++ b/lib/includes/hicn/interest_manifest.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 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 HICNLIGHT_INTEREST_MANIFEST_H
+#define HICNLIGHT_INTEREST_MANIFEST_H
+
+#include <string.h>
+#include <stdbool.h>
+
+#include <hicn/util/bitmap.h>
+#include <hicn/base.h>
+
+typedef enum
+{
+ INT_MANIFEST_SPLIT_STRATEGY_NONE,
+ INT_MANIFEST_SPLIT_STRATEGY_MAX_N_SUFFIXES,
+ INT_MANIFEST_SPLIT_N_STRATEGIES,
+} int_manifest_split_strategy_t;
+
+#define MAX_SUFFIXES_IN_MANIFEST 256
+
+#define DEFAULT_DISAGGREGATION_STRATEGY \
+ INT_MANIFEST_SPLIT_STRATEGY_MAX_N_SUFFIXES
+#define DEFAULT_N_SUFFIXES_PER_SPLIT MAX_SUFFIXES_IN_MANIFEST
+
+#define BITMAP_SIZE (MAX_SUFFIXES_IN_MANIFEST / WORD_WIDTH)
+
+typedef struct
+{
+ /* This can be 16 bits, but we use 32 bits for alignment */
+ uint32_t n_suffixes;
+
+ /* Align to 64 bits */
+ uint32_t padding;
+
+ hicn_uword request_bitmap[BITMAP_SIZE];
+
+ /* Followed by the list of prefixes to ask */
+ /* ... */
+} interest_manifest_header_t;
+
+static_assert (sizeof (interest_manifest_header_t) == 32 + 4 + 4,
+ "interest_manifest_header_t size must be 40 bytes");
+
+static inline bool
+interest_manifest_is_valid (interest_manifest_header_t *int_manifest_header,
+ size_t payload_length)
+{
+ if (int_manifest_header->n_suffixes == 0 ||
+ int_manifest_header->n_suffixes > MAX_SUFFIXES_IN_MANIFEST)
+ {
+ return false;
+ }
+
+ hicn_uword empty_bitmap[BITMAP_SIZE] = { 0 };
+ if (memcmp (empty_bitmap, int_manifest_header->request_bitmap,
+ sizeof (empty_bitmap)) == 0)
+ {
+ return false;
+ }
+
+ if (payload_length - sizeof (interest_manifest_header_t) !=
+ int_manifest_header->n_suffixes * sizeof (u32))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static inline size_t
+interest_manifest_update_bitmap (const hicn_uword *initial_bitmap,
+ hicn_uword *bitmap_to_update, size_t start,
+ size_t n, size_t max_suffixes)
+{
+ size_t i = start, n_ones = 0;
+ while (i < n)
+ {
+ if (bitmap_is_set_no_check (initial_bitmap, i))
+ {
+ bitmap_set_no_check (bitmap_to_update, i);
+ n_ones++;
+ }
+ i++;
+
+ if (n_ones == max_suffixes)
+ break;
+ }
+
+ return i;
+}
+
+#endif /* HICNLIGHT_INTEREST_MANIFEST_H */
diff --git a/lib/includes/hicn/mapme.h b/lib/includes/hicn/mapme.h
index 63a5cd77e..b452a5dde 100644
--- a/lib/includes/hicn/mapme.h
+++ b/lib/includes/hicn/mapme.h
@@ -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:
@@ -23,9 +23,9 @@
#include <stdint.h> // u32
#include <stdbool.h>
+#include <hicn/name.h>
+
#include "common.h"
-#include "protocol.h"
-#include "ops.h"
/**
* @brief MAP-Me configuration options
@@ -114,51 +114,11 @@ int hicn_mapme_parse_packet (const u8 *packet, hicn_prefix_t *prefix,
/* Default TTL */
#define HICN_MAPME_TTL 255 // typical for redirect (ref?)
-/*
- * The length of the MAPME4 header struct must be 120 bytes.
- */
-#define EXPECTED_MAPME_V4_HDRLEN 120
-
-/** @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;
+/* Should be moved to mapme.c, but header size still in use in VPP */
-/*
- * The length of the MAPME4 header struct must be bytes.
- */
+#define EXPECTED_MAPME_V4_HDRLEN 120
#define EXPECTED_MAPME_V6_HDRLEN 88
-/** @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.");
-
#endif /* HICN_MAPME_H */
/*
diff --git a/lib/includes/hicn/name.h b/lib/includes/hicn/name.h
index f85b0bc3f..895b86341 100644
--- a/lib/includes/hicn/name.h
+++ b/lib/includes/hicn/name.h
@@ -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:
@@ -24,12 +24,14 @@
#ifndef HICN_NAME_H
#define HICN_NAME_H
+#include <assert.h>
#include <stdbool.h>
+#include <stddef.h>
#ifndef _WIN32
#include <netinet/in.h> // struct sockadd
#endif
+#include <hicn/common.h>
#include <hicn/util/ip_address.h>
-#include "common.h"
/******************************************************************************
* hICN names
@@ -38,40 +40,92 @@
#define TCP_SEQNO_LEN 4 /* bytes */
#define HICN_V4_PREFIX_LEN IPV4_ADDR_LEN
#define HICN_V6_PREFIX_LEN IPV6_ADDR_LEN
-#define HICN_SEGMENT_LEN TCP_SEQNO_LEN
+
+#if 0
+#define HICN_SEGMENT_LEN TCP_SEQNO_LEN
+
#define HICN_V6_NAME_LEN \
(HICN_V6_PREFIX_LEN + HICN_SEGMENT_LEN) /* 20 bytes \
*/
#define HICN_V4_NAME_LEN \
(HICN_V4_PREFIX_LEN + HICN_SEGMENT_LEN) /* 8 bytes \
*/
+#endif
+
+#define HICN_INVALID_SUFFIX ((uint32_t) (~0))
/* Prefix */
-typedef u32 hicn_name_suffix_t;
+#define HICN_PREFIX_MAX_LEN IP_ADDRESS_MAX_LEN
typedef struct
{
- ip_address_t name;
+ hicn_ip_address_t name;
u8 len;
} hicn_prefix_t;
+#define HICN_PREFIX_EMPTY \
+ (hicn_prefix_t) { .name = IP_ADDRESS_EMPTY, .len = 0 }
+
+static inline const hicn_ip_address_t *
+hicn_prefix_get_ip_address (const hicn_prefix_t *prefix)
+{
+ return &prefix->name;
+}
+
+static inline u8
+hicn_prefix_get_len (const hicn_prefix_t *prefix)
+{
+ return prefix->len;
+}
+
+int hicn_prefix_get_ip_prefix (const hicn_prefix_t *prefix,
+ hicn_ip_prefix_t *ip_prefix);
/*
* Name
*
* A name is a prefix + a segment name (suffix)
*/
+typedef hicn_ip_address_t hicn_name_prefix_t;
+typedef uint32_t hicn_name_suffix_t;
+
+#define hicn_name_prefix_cmp hicn_ip_address_cmp
+#define hicn_name_prefix_equals hicn_ip_address_equals
+#define hicn_name_prefix_get_len_bits hicn_ip_address_get_len_bits
+#define hicn_name_prefix_get_hash hicn_ip_address_get_hash
+#define hicn_name_prefix_snprintf hicn_ip_address_snprintf
+#define HICN_NAME_PREFIX_EMPTY IP_ADDRESS_EMPTY
+
typedef struct
{
- ip_address_t prefix;
+ hicn_name_prefix_t prefix;
hicn_name_suffix_t suffix;
} hicn_name_t;
+static_assert (offsetof (hicn_name_t, prefix) == 0, "");
+static_assert (offsetof (hicn_name_t, suffix) == 16, "");
+static_assert (sizeof (hicn_name_t) == 20, "");
+
+#define HICN_NAME_EMPTY \
+ (hicn_name_t) { .prefix = HICN_NAME_PREFIX_EMPTY, .suffix = 0, }
+
+static inline const hicn_name_prefix_t *
+hicn_name_get_prefix (const hicn_name_t *name)
+{
+ return &name->prefix;
+}
+
+static inline const hicn_name_suffix_t
+hicn_name_get_suffix (const hicn_name_t *name)
+{
+ return name->suffix;
+}
+
#define _is_unspec(name) \
(((name)->prefix.pad[0] | (name)->prefix.pad[1] | (name)->prefix.pad[2] | \
(name)->prefix.v4.as_u32) == 0)
-#define _is_inet4(name) (ip_address_is_v4 (&name->prefix))
+#define _is_inet4(name) (hicn_ip_address_is_v4 (&name->prefix))
#define _is_inet6(name) (!_is_inet4 (name))
/**
@@ -86,11 +140,21 @@ int hicn_name_create (const char *ip_address, u32 id, hicn_name_t *name);
/**
* @brief Create an hICN name from IP address
* @param [in] ip_address - IP address
- * @param [in] id Segment - identifier
+ * @param [in] suffix - Name suffix
* @param [out] Resulting - hICN name
* @return hICN error code
*/
-int hicn_name_create_from_ip_prefix (const ip_prefix_t *prefix, u32 id,
+int hicn_name_create_from_ip_address (const hicn_ip_address_t ip_address,
+ u32 suffix, hicn_name_t *name);
+
+/**
+ * @brief Create an hICN name from IP prefix
+ * @param [in] prefix - IP prefix
+ * @param [in] suffix - Name suffix
+ * @param [out] Resulting - hICN name
+ * @return hICN error code
+ */
+int hicn_name_create_from_ip_prefix (const hicn_ip_prefix_t *prefix, u32 id,
hicn_name_t *name);
/**
@@ -113,7 +177,10 @@ int hicn_name_compare (const hicn_name_t *name_1, const hicn_name_t *name_2,
* @param [in] consider_suffix - Consider the suffix in the hash computation
* @return hICN error code
*/
-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);
+
+#define hicn_name_get_hash(NAME) _hicn_name_get_hash (NAME, true)
+#define hicn_name_get_prefix_hash(NAME) _hicn_name_get_hash (NAME, false)
/**
* @brief Test whether an hICN name is empty
@@ -146,7 +213,7 @@ int hicn_name_copy_prefix_to_destination (u8 *dst, const hicn_name_t *src);
* @param [in] seq_number - Segment identifier
* @return hICN error code
*/
-int hicn_name_set_seq_number (hicn_name_t *name, u32 seq_number);
+int hicn_name_set_suffix (hicn_name_t *name, hicn_name_suffix_t suffix);
/**
* @brief Retrieves the segment part of an hICN name
@@ -171,7 +238,8 @@ int hicn_name_to_sockaddr_address (const hicn_name_t *name,
* @param [out] ip_address - Resulting IP address
* @return hICN error code
*/
-int hicn_name_to_ip_prefix (const hicn_name_t *name, ip_prefix_t *ip_prefix);
+int hicn_name_to_hicn_ip_prefix (const hicn_name_t *name,
+ hicn_ip_prefix_t *hicn_ip_prefix);
/**
* @brief Convert an hICN name to presentation format
@@ -198,15 +266,50 @@ int hicn_name_pton (const char *src, hicn_name_t *dst);
*/
int hicn_name_get_family (const hicn_name_t *name, int *family);
+bool hicn_name_is_v4 (const hicn_name_t *name);
+
+int hicn_name_snprintf (char *s, size_t size, const hicn_name_t *name);
+
+int hicn_name_cmp (const hicn_name_t *n1, const hicn_name_t *n2);
+bool hicn_name_equals (const hicn_name_t *n1, const hicn_name_t *n2);
+
+#define MAXSZ_HICN_NAME MAXSZ_IP_ADDRESS
+
/**
* @brief Creates an hICN prefix from an IP address
* @param [in] ip_address - Input IP address
* @param [out] prefix - Resulting prefix
* @return hICN error code
*/
-int hicn_prefix_create_from_ip_prefix (const ip_prefix_t *ip_prefix,
+int hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix,
hicn_prefix_t *prefix);
+int
+hicn_prefix_create_from_ip_address_len (const hicn_ip_address_t *ip_address,
+ uint8_t len, hicn_prefix_t *prefix);
+
+hicn_prefix_t *hicn_prefix_dup (const hicn_prefix_t *prefix);
+
+int hicn_prefix_copy (hicn_prefix_t *dst, const hicn_prefix_t *src);
+
+bool hicn_prefix_is_v4 (const hicn_prefix_t *prefix);
+
+uint32_t hicn_prefix_lpm (const hicn_prefix_t *p1, const hicn_prefix_t *p2);
+
+void hicn_prefix_clear (hicn_prefix_t *prefix, uint8_t start_from);
+
+void hicn_prefix_truncate (hicn_prefix_t *prefix, uint8_t len);
+
+int hicn_prefix_cmp (const hicn_prefix_t *p1, const hicn_prefix_t *p2);
+
+bool hicn_prefix_equals (const hicn_prefix_t *p1, const hicn_prefix_t *p2);
+
+int hicn_prefix_snprintf (char *s, size_t size, const hicn_prefix_t *prefix);
+
+uint8_t hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos);
+
+#define MAXSZ_HICN_PREFIX MAXSZ_IP_PREFIX
+
#endif /* HICN_NAME_H */
/*
diff --git a/lib/includes/hicn/ops.h b/lib/includes/hicn/ops.h
deleted file mode 100644
index 4efef6523..000000000
--- a/lib/includes/hicn/ops.h
+++ /dev/null
@@ -1,1029 +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 base.h
- * @brief Protocol-independent packet operations
- */
-
-#ifndef HICN_OPS_H
-#define HICN_OPS_H
-
-#include <stdlib.h>
-
-#include "common.h"
-#include "error.h"
-#include "header.h"
-#include "name.h"
-
-/*
- * 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
-{
- /**
- * @brief Initialize the headers of the hicn packet
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the packet
- */
- int (*init_packet_header) (hicn_type_t type, hicn_protocol_t *h);
-
- /**
- * @brief Retrieves an Interest locator
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest packet
- * @param [out] ip_address - Retrieved locator
- * @return hICN error code
- */
- int (*get_interest_locator) (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address);
-
- /**
- * @brief Sets an Interest locator
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest packet
- * @param [in] ip_address - Locator to set
- * @return hICN error code
- */
- int (*set_interest_locator) (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address);
-
- /**
- * @brief Retrieves an Interest name
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest packet
- * @param [out] name - Retrieved name
- * @return hICN error code
- */
- int (*get_interest_name) (hicn_type_t type, const hicn_protocol_t *h,
- hicn_name_t *name);
-
- /**
- * @brief Sets an Interest name
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest packet
- * @param [in] name - Name to set
- * @return hICN error code
- */
- int (*set_interest_name) (hicn_type_t type, hicn_protocol_t *h,
- const hicn_name_t *name);
-
- /**
- * @brief Retrieves an Interest name suffix
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest packet
- * @param [out] suffix - Retrieved name suffix
- * @return hICN error code
- */
- int (*get_interest_name_suffix) (hicn_type_t type, const hicn_protocol_t *h,
- hicn_name_suffix_t *suffix);
-
- /**
- * @brief Sets an Interest name suffix
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest packet
- * @param [in] suffix - Name suffix to set
- * @return hICN error code
- */
- int (*set_interest_name_suffix) (hicn_type_t type, hicn_protocol_t *h,
- const hicn_name_suffix_t *suffix);
-
- /**
- * @brief Check if packet is an interest
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest packet
- * @param [out] h - 1 if interest, 0 otherwise
- * @return hICN error code
- */
- int (*is_interest) (hicn_type_t type, const hicn_protocol_t *h, int *ret);
-
- /**
- * @brief Set flag to mark current packet as interest
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest packet
- * @return hICN error code
- */
- int (*mark_packet_as_interest) (hicn_type_t type, hicn_protocol_t *h);
-
- /**
- * @brief Set flag to mark current packet as data
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest packet
- * @return hICN error code
- */
- int (*mark_packet_as_data) (hicn_type_t type, hicn_protocol_t *h);
-
- /**
- * @brief Clear the necessary Interest fields in order to hash it
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest packet
- * @return hICN error code
- */
- int (*reset_interest_for_hash) (hicn_type_t type, hicn_protocol_t *h);
-
- /**
- * @brief Retrieves a Data locator
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Data packet
- * @param [out] ip_address - Retrieved locator
- * @return hICN error code
- */
- int (*get_data_locator) (hicn_type_t type, const hicn_protocol_t *h,
- ip_address_t *ip_address);
-
- /**
- * @brief Sets a Data locator
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Data packet
- * @param [in] ip_address - Locator to set
- * @return hICN error code
- */
- int (*set_data_locator) (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *ip_address);
-
- /**
- * @brief Retrieves a Data name
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Data packet
- * @param [out] name - Retrieved name
- * @return hICN error code
- */
- int (*get_data_name) (hicn_type_t type, const hicn_protocol_t *h,
- hicn_name_t *name);
-
- /**
- * @brief Sets a Data name
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Data packet
- * @param [in] name - Name to set
- * @return hICN error code
- */
- int (*set_data_name) (hicn_type_t type, hicn_protocol_t *h,
- const hicn_name_t *name);
-
- /**
- * @brief Retrieves a Data name suffix
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Data packet
- * @param [out] suffix - Retrieved name suffix
- * @return hICN error code
- */
- int (*get_data_name_suffix) (hicn_type_t type, const hicn_protocol_t *h,
- hicn_name_suffix_t *suffix);
-
- /**
- * @brief Sets a Data name suffix
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Data packet
- * @param [in] suffix - Name suffix to set
- * @return hICN error code
- */
- int (*set_data_name_suffix) (hicn_type_t type, hicn_protocol_t *h,
- const hicn_name_suffix_t *suffix);
-
- /**
- * @brief Retrieves a Data pathlabel
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Data packet
- * @param [out] pathlabel - Retrieved pathlabel
- * @return hICN error code
- */
- int (*get_data_pathlabel) (hicn_type_t type, const hicn_protocol_t *h,
- u32 *pathlabel);
-
- /**
- * @brief Sets a Data pathlabel
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Data packet
- * @param [in] pathlabel - Pathlabel to set
- * @return hICN error code
- */
- int (*set_data_pathlabel) (hicn_type_t type, hicn_protocol_t *h,
- const u32 pathlabel);
-
- /**
- * @brief Update a Data pathlabel with a new face identifier
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Data packet
- * @param [in] pathlabel - Face identifier used to update pathlabel
- * @return hICN error code
- */
- int (*update_data_pathlabel) (hicn_type_t type, hicn_protocol_t *h,
- const hicn_faceid_t face_id);
-
- /**
- * @brief Clear the necessary Data fields in order to hash it
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Data packet
- * @return hICN error code
- */
- int (*reset_data_for_hash) (hicn_type_t type, hicn_protocol_t *h);
-
- /**
- * @brief Retrieves an Interest or Data lifetime
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] pathlabel - Retrieved lifetime
- * @return hICN error code
- */
- int (*get_lifetime) (hicn_type_t type, const hicn_protocol_t *h,
- hicn_lifetime_t *lifetime);
-
- /**
- * @brief Sets an Interest or Data lifetime
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] pathlabel - Lifetime to set
- * @return hICN error code
- */
- int (*set_lifetime) (hicn_type_t type, hicn_protocol_t *h,
- const hicn_lifetime_t lifetime);
-
- /**
- * @brief Get the source port of the hicn packet.
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] source_port - Retrieved source port
- * @return hICN error code
- */
- int (*get_source_port) (hicn_type_t type, const hicn_protocol_t *h,
- u16 *source_port);
-
- /**
- * @brief Get the destination port of the hicn packet.
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] source_port - Retrieved destination port
- * @return hICN error code
- */
- int (*get_dest_port) (hicn_type_t type, const hicn_protocol_t *h,
- u16 *dest_port);
-
- /**
- * @brief Set the source port of the hicn packet.
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] source_port - Source port to set
- * @return hICN error code
- */
- int (*set_source_port) (hicn_type_t type, hicn_protocol_t *h,
- u16 source_port);
-
- /**
- * @brief Set the destination port of the hicn packet.
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] source_port - Destination port to set
- * @return hICN error code
- */
- int (*set_dest_port) (hicn_type_t type, hicn_protocol_t *h, u16 dest_port);
-
- /**
- * @brief Update all checksums in packet headers
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the packet
- * @param [in] partial_csum - Partial checksum (set to 0, used internally to
- * carry intermediate values from IP pseudo-header)
- * @param [in] payload_length - Payload length (can be set to ~0, retrieved
- * and used internally to carry payload length across protocol headers)
- * @return hICN error code
- */
- int (*update_checksums) (hicn_type_t type, hicn_protocol_t *h,
- u16 partial_csum, size_t payload_length);
-
- /**
- * @brief Validate all checksums in packet headers
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the packet
- * @param [in] partial_csum - Partial checksum, or zero if no partial
- * checksum available
- * @param [in] payload_length - Payload length (can be set to ~0, retrieved
- * and used internally to carry payload length across protocol headers)
- * @return hICN error code
- */
- int (*verify_checksums) (hicn_type_t type, hicn_protocol_t *h,
- u16 partial_csum, size_t payload_length);
-
- /**
- * @brief Rewrite an Interest packet header (locator)
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest packet
- * @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) (hicn_type_t type, hicn_protocol_t *h,
- const ip_address_t *addr_new,
- ip_address_t *addr_old);
-
- /**
- * @brief Rewrite a Data packet header (locator + pathlabel)
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Data packet
- * @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 pathlabel
- * @param [in] reset_pl - If not zero, reset the current pathlabel
- * before update it
- * @return hICN error code
- */
- int (*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);
-
- /**
- * @brief Return the packet length
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the packet
- * @parma [out] length - Returned packet length
- * @return hICN error code
- */
- int (*get_length) (hicn_type_t type, const hicn_protocol_t *h,
- size_t *length);
-
- /**
- * @brief Return the current packet header length
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the packet
- * @parma [out] header_length - Returned packet current header length
- * @return hICN error code
- */
- int (*get_current_header_length) (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length);
-
- /**
- * @brief Return the packet header length
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the packet
- * @parma [out] header_length - Returned packet header length
- * @return hICN error code
- */
- int (*get_header_length) (hicn_type_t type, const hicn_protocol_t *h,
- size_t *header_length);
-
- /**
- * @brief Return the packet payload length
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the packet
- * @parma [out] payload_length - Returned packet payload length
- * @return hICN error code
- */
- int (*get_payload_length) (hicn_type_t type, const hicn_protocol_t *h,
- size_t *payload_length);
-
- /**
- * @brief Sets the packet paylaod length
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the packet
- * @parma [out] payload_length - Payload length to set
- * @return hICN error code
- */
- int (*set_payload_length) (hicn_type_t type, hicn_protocol_t *h,
- size_t payload_length);
-
- /**
- * @brief Retrieves an Interest or Data signature size
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] signature_size - Retrieved signature size
- * @return hICN error code
- */
- int (*get_signature_size) (hicn_type_t type, const hicn_protocol_t *h,
- size_t *signature_size);
-
- /**
- * @brief Sets an Interest or Data signature size
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] signature_size - Signature size to set
- * @return hICN error code
- */
- int (*set_signature_size) (hicn_type_t type, hicn_protocol_t *h,
- size_t signature_size);
-
- /**
- * @brief Sets an Interest or Data signature padding between maximum size and
- * real size
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] signature_size - Signature size to set
- * @return hICN error code
- */
- int (*set_signature_padding) (hicn_type_t type, hicn_protocol_t *h,
- size_t signature_padding);
-
- /**
- * @brief gets an Interest or Data signature padding between maximum size and
- * real size
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] signature_size - retrieve the padding between maximum size and
- * real size
- * @return hICN error code
- */
- int (*get_signature_padding) (hicn_type_t type, const hicn_protocol_t *h,
- size_t *signature_padding);
-
- /**
- * @brief Gets the signature timestamp
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [out] signature_timestamp - Retrieved signature timestamp
- * @return hICN error code
- */
- int (*get_signature_timestamp) (hicn_type_t type, const hicn_protocol_t *h,
- uint64_t *signature_timestamp);
-
- /**
- * @brief Sets the signature timestamp
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] signature_timestamp - Signature timestamp to set
- * @return hICN error code
- */
- int (*set_signature_timestamp) (hicn_type_t type, hicn_protocol_t *h,
- uint64_t signature_timestamp);
-
- /**
- * @brief Gets the signature validation algorithm
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [out] validation_algorithm - Retrieved validation_algorithm
- * @return hICN error code
- */
- int (*get_validation_algorithm) (hicn_type_t type, const hicn_protocol_t *h,
- uint8_t *validation_algorithm);
-
- /**
- * @brief Sets the signature validation algorithm
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] validation_algorithm - Validation algorithm enumeration
- * @return hICN error code
- */
- int (*set_validation_algorithm) (hicn_type_t type, hicn_protocol_t *h,
- uint8_t validation_algorithm);
-
- /**
- * @brief Gets the key id
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [out] key_id - Retrieved key id first byte address
- * @return hICN error code
- */
- int (*get_key_id) (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id,
- uint8_t *key_id_size);
-
- /**
- * @brief Sets the key id
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] key_id - Key id first byte address
- * @return hICN error code
- */
- int (*set_key_id) (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id);
-
- /**
- * @brief Get a pointer to the signature field in the packet
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [out] signature - Pointer to the memory region holding the
- * signature
- * @return hICN error code
- */
- int (*get_signature) (hicn_type_t type, hicn_protocol_t *h,
- uint8_t **signature);
-
- /**
- * @brief Set payload type of the packet
- * @param [in] type - hICN packet type
- * @param [in,out] h - Buffer holding the Interest or Data packet
- * @param [in] payload_type - The payload type of this packet
- * @return hICN error code
- */
- int (*set_payload_type) (hicn_type_t type, hicn_protocol_t *h,
- hicn_payload_type_t payload_type);
-
- /**
- * @brief Get payload type from the packet
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] payload_type - The payload type of this packet
- * @return hICN error code
- */
- int (*get_payload_type) (hicn_type_t type, const hicn_protocol_t *h,
- hicn_payload_type_t *payload_type);
-
- /**
- * @brief Check if data packet is last one.
- * @param [in] type - hICN packet type
- * @param [in] h - Buffer holding the Interest or Data packet
- * @param [out] is_last - 1 if last data, 0 otherwise
- * @return hICN error code
- */
- int (*is_last_data) (hicn_type_t type, const hicn_protocol_t *h,
- int *is_last);
-
- /**
- * @brief Mark data packet as last
- * @param [in] type - hICN packet type
- * @param [in, out] h - Buffer holding the Interest or Data packet
- * @return hICN error code
- */
- int (*set_last_data) (hicn_type_t type, hicn_protocol_t *h);
-} hicn_ops_t;
-
-#define DECLARE_HICN_OPS(protocol) \
- const hicn_ops_t hicn_ops_##protocol = { \
- 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 (is_interest, protocol##_is_interest), \
- ATTR_INIT (mark_packet_as_interest, protocol##_mark_packet_as_interest), \
- ATTR_INIT (mark_packet_as_data, protocol##_mark_packet_as_data), \
- 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_pathlabel, protocol##_get_data_pathlabel), \
- ATTR_INIT (set_data_pathlabel, protocol##_set_data_pathlabel), \
- ATTR_INIT (update_data_pathlabel, protocol##_update_data_pathlabel), \
- 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 (get_source_port, protocol##_get_source_port), \
- ATTR_INIT (get_dest_port, protocol##_get_dest_port), \
- ATTR_INIT (set_source_port, protocol##_set_source_port), \
- ATTR_INIT (set_dest_port, protocol##_set_dest_port), \
- ATTR_INIT (update_checksums, protocol##_update_checksums), \
- ATTR_INIT (verify_checksums, protocol##_verify_checksums), \
- ATTR_INIT (rewrite_interest, protocol##_rewrite_interest), \
- ATTR_INIT (rewrite_data, protocol##_rewrite_data), \
- ATTR_INIT (get_length, protocol##_get_length), \
- ATTR_INIT (get_current_header_length, \
- protocol##_get_current_header_length), \
- ATTR_INIT (get_header_length, protocol##_get_header_length), \
- ATTR_INIT (get_payload_length, protocol##_get_payload_length), \
- ATTR_INIT (set_payload_length, protocol##_set_payload_length), \
- 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 (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 (set_last_data, protocol##_set_last_data), \
- }
-
-/**
- * @brief Protocol-independent packet operations VFT
- * NOTE: The following declarations should be kept in order
- */
-extern const hicn_ops_t *const hicn_ops_vft[];
-
-/*
- * Helpers for writing recursive protocol operations on packet headers
- *
- * NOTE : we cannot use a shift operation as IPPROTO_NONE != 0 (and 0 is
- * IPv4...)
- */
-static inline hicn_type_t
-TYPE_POP (hicn_type_t type)
-{
-#ifndef _WIN32
- return HICN_TYPE (type.l2, type.l3, type.l4, IPPROTO_NONE);
-#else
- hicn_type_t new_type;
- new_type.l1 = type.l2;
- new_type.l2 = type.l3;
- new_type.l3 = type.l4;
- new_type.l4 = IPPROTO_NONE;
- return new_type;
-#endif
-}
-
-static inline hicn_protocol_t *
-PAYLOAD (hicn_type_t type, const hicn_protocol_t *h)
-{
- size_t header_length;
- int rc =
- hicn_ops_vft[type.l1]->get_current_header_length (type, h, &header_length);
- if (rc < 0)
- return NULL;
- return (hicn_protocol_t *) ((u8 *) h + header_length);
-}
-
-#define CHILD_OPS(f, type, h, ...) \
- (hicn_ops_vft[type.l2]->f (TYPE_POP (type), PAYLOAD (type, h), \
- ##__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_type_t type, hicn_protocol_t *h) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_interest_locator(protocol, error) \
- int protocol##_get_interest_locator ( \
- hicn_type_t type, const hicn_protocol_t *h, ip_address_t *ip_address) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_interest_locator(protocol, error) \
- int protocol##_set_interest_locator (hicn_type_t type, hicn_protocol_t *h, \
- const ip_address_t *ip_address) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_interest_name(protocol, error) \
- int protocol##_get_interest_name ( \
- hicn_type_t type, const hicn_protocol_t *h, hicn_name_t *name) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_interest_name(protocol, error) \
- int protocol##_set_interest_name (hicn_type_t type, hicn_protocol_t *h, \
- const hicn_name_t *name) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_interest_name_suffix(protocol, error) \
- int protocol##_get_interest_name_suffix ( \
- hicn_type_t type, const hicn_protocol_t *h, hicn_name_suffix_t *suffix) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_interest_name_suffix(protocol, error) \
- int protocol##_set_interest_name_suffix ( \
- hicn_type_t type, hicn_protocol_t *h, const hicn_name_suffix_t *suffix) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_is_interest(protocol, error) \
- int protocol##_is_interest (hicn_type_t type, const hicn_protocol_t *h, \
- int *ret) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_mark_packet_as_interest(protocol, error) \
- int protocol##_mark_packet_as_interest (hicn_type_t type, \
- hicn_protocol_t *h) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_mark_packet_as_data(protocol, error) \
- int protocol##_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_reset_interest_for_hash(protocol, error) \
- int protocol##_reset_interest_for_hash (hicn_type_t type, \
- hicn_protocol_t *h) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_data_locator(protocol, error) \
- int protocol##_get_data_locator ( \
- hicn_type_t type, const hicn_protocol_t *h, ip_address_t *ip_address) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_data_locator(protocol, error) \
- int protocol##_set_data_locator (hicn_type_t type, hicn_protocol_t *h, \
- const ip_address_t *ip_address) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_data_name(protocol, error) \
- int protocol##_get_data_name (hicn_type_t type, const hicn_protocol_t *h, \
- hicn_name_t *name) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_data_name(protocol, error) \
- int protocol##_set_data_name (hicn_type_t type, hicn_protocol_t *h, \
- const hicn_name_t *name) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_data_name_suffix(protocol, error) \
- int protocol##_get_data_name_suffix ( \
- hicn_type_t type, const hicn_protocol_t *h, hicn_name_suffix_t *suffix) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_data_name_suffix(protocol, error) \
- int protocol##_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, \
- const hicn_name_suffix_t *suffix) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_data_pathlabel(protocol, error) \
- int protocol##_get_data_pathlabel ( \
- hicn_type_t type, const hicn_protocol_t *h, u32 *pathlabel) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_data_pathlabel(protocol, error) \
- int protocol##_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, \
- const u32 pathlabel) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_update_data_pathlabel(protocol, error) \
- int protocol##_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, \
- 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_type_t type, hicn_protocol_t *h) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_lifetime(protocol, error) \
- int protocol##_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, \
- hicn_lifetime_t *lifetime) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_lifetime(protocol, error) \
- int protocol##_set_lifetime (hicn_type_t type, hicn_protocol_t *h, \
- const hicn_lifetime_t lifetime) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_source_port(protocol, error) \
- int protocol##_get_source_port (hicn_type_t type, const hicn_protocol_t *h, \
- u16 *source_port) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_dest_port(protocol, error) \
- int protocol##_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, \
- u16 *dest_port) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_source_port(protocol, error) \
- int protocol##_set_source_port (hicn_type_t type, hicn_protocol_t *h, \
- u16 source_port) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_dest_port(protocol, error) \
- int protocol##_set_dest_port (hicn_type_t type, hicn_protocol_t *h, \
- u16 dest_port) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_update_checksums(protocol, error) \
- int protocol##_update_checksums (hicn_type_t type, hicn_protocol_t *h, \
- u16 partial_csum, size_t payload_length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_verify_checksums(protocol, error) \
- int protocol##_verify_checksums (hicn_type_t type, hicn_protocol_t *h, \
- u16 partial_csum, size_t payload_length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_rewrite_interest(protocol, error) \
- int protocol##_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, \
- const ip_address_t *addr_new, \
- ip_address_t *addr_old) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_rewrite_data(protocol, error) \
- int protocol##_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) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_length(protocol, error) \
- int protocol##_get_length (hicn_type_t type, const hicn_protocol_t *h, \
- size_t *length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_current_header_length(protocol, error) \
- int protocol##_get_current_header_length ( \
- hicn_type_t type, const hicn_protocol_t *h, size_t *header_length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_header_length(protocol, error) \
- int protocol##_get_header_length ( \
- hicn_type_t type, const hicn_protocol_t *h, size_t *header_length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_payload_length(protocol, error) \
- int protocol##_get_payload_length ( \
- hicn_type_t type, const hicn_protocol_t *h, size_t *payload_length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_payload_length(protocol, error) \
- int protocol##_set_payload_length (hicn_type_t type, hicn_protocol_t *h, \
- size_t payload_length) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_payload_type(protocol, error) \
- int protocol##_get_payload_type (hicn_type_t type, \
- const hicn_protocol_t *h, \
- hicn_payload_type_t *payload_type) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_payload_type(protocol, error) \
- int protocol##_set_payload_type (hicn_type_t type, hicn_protocol_t *h, \
- hicn_payload_type_t payload_type) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_signature_size(protocol, error) \
- int protocol##_get_signature_size ( \
- hicn_type_t type, const hicn_protocol_t *h, size_t *signature_size) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_signature_size(protocol, error) \
- int protocol##_set_signature_size (hicn_type_t type, hicn_protocol_t *h, \
- size_t signature_size) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_signature_padding(protocol, error) \
- int protocol##_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, \
- size_t padding) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_signature_padding(protocol, error) \
- int protocol##_get_signature_padding ( \
- hicn_type_t type, const hicn_protocol_t *h, size_t *padding) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_signature_timestamp(protocol, error) \
- int protocol##_set_signature_timestamp ( \
- hicn_type_t type, hicn_protocol_t *h, uint64_t signature_timestamp) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_signature_timestamp(protocol, error) \
- int protocol##_get_signature_timestamp (hicn_type_t type, \
- const hicn_protocol_t *h, \
- uint64_t *signature_timestamp) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_validation_algorithm(protocol, error) \
- int protocol##_set_validation_algorithm ( \
- hicn_type_t type, hicn_protocol_t *h, uint8_t validation_algorithm) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_validation_algorithm(protocol, error) \
- int protocol##_get_validation_algorithm (hicn_type_t type, \
- const hicn_protocol_t *h, \
- uint8_t *validation_algorithm) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_key_id(protocol, error) \
- int protocol##_set_key_id (hicn_type_t type, hicn_protocol_t *h, \
- uint8_t *key_id) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_key_id(protocol, error) \
- int protocol##_get_key_id (hicn_type_t type, hicn_protocol_t *h, \
- uint8_t **key_id, uint8_t *key_id_size) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_get_signature(protocol, error) \
- int protocol##_get_signature (hicn_type_t type, hicn_protocol_t *h, \
- uint8_t **signature) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_is_last_data(protocol, error) \
- int protocol##_is_last_data (hicn_type_t type, const hicn_protocol_t *h, \
- int *is_last) \
- { \
- return HICN_LIB_ERROR_##error; \
- }
-
-#define DECLARE_set_last_data(protocol, error) \
- int protocol##_set_last_data (hicn_type_t type, hicn_protocol_t *h) \
- { \
- 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/includes/hicn/packet.h b/lib/includes/hicn/packet.h
new file mode 100644
index 000000000..c64014fe6
--- /dev/null
+++ b/lib/includes/hicn/packet.h
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 2017-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 compat.h
+ * @brief Implementation of the compatibility layer.
+ *
+ * The structure of the core API has evolved to support operations of a variety
+ * of packet formats in addition to IPv4/TCP and IPv6/TCP, namely with the use
+ * of ICMP for signalization and AH headers for integrity. The new API format
+ * has been designed to scale better with the multiplicity of packet formats,
+ * and provide a unified interface on top. We maintain an interface for the
+ * former API in this file, which mainly acts as a wrapper on top of new calls.
+ *
+ */
+#ifndef HICN_PACKET_H
+#define HICN_PACKET_H
+
+#include <limits.h>
+
+#include <hicn/base.h>
+#include <hicn/common.h>
+#include <hicn/name.h>
+
+/* Packet buffer definition */
+
+typedef struct __attribute__ ((packed))
+{
+ /* Packet format */
+ hicn_packet_format_t format;
+
+ /* Packet type */
+ hicn_packet_type_t type;
+
+ /*
+ * We store an offset to the packet header.
+ *
+ * NOTE: This is a signed value.
+ *
+ * In most implementations, the buffer located closeby to the current packet
+ * buffer (eg msgbuf in hicn-light, and vlib buffer in VPP), and an int16_t
+ * would be sufficient. This is not the case in transport though and we have
+ * to use a full integer.
+ */
+ int64_t header;
+
+ /* Packet len */
+ uint16_t len;
+
+#ifdef OPAQUE_IP
+ /* Interest or data packet */
+ union
+ {
+ uint16_t ipv4;
+ uint16_t ipv6;
+ };
+#endif /* OPAQUE_IP */
+ union
+ {
+ uint16_t tcp;
+ uint16_t udp;
+ uint16_t icmp;
+ };
+ uint16_t newhdr;
+ uint16_t ah;
+ uint16_t payload;
+
+ uint16_t buffer_size;
+ // uint16_t len;
+
+ /* Contiguous copy of the name */
+ // hicn_name_t *name;
+
+} hicn_packet_buffer_t;
+
+static_assert (sizeof (hicn_packet_buffer_t) == 28, "");
+
+static inline uint8_t *
+_pkbuf_get_ipv4 (const hicn_packet_buffer_t *pkbuf)
+{
+#ifdef OPAQUE_IP
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->ipv4;
+#else
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header;
+#endif
+ _ASSERT (header);
+ return header;
+}
+#define pkbuf_get_ipv4(pkbuf) ((_ipv4_header_t *) (_pkbuf_get_ipv4 (pkbuf)))
+
+static inline uint8_t *
+_pkbuf_get_ipv6 (const hicn_packet_buffer_t *pkbuf)
+{
+#ifdef OPAQUE_IP
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->ipv6;
+#else
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header;
+#endif
+ assert (header);
+ return header;
+}
+#define pkbuf_get_ipv6(pkbuf) ((_ipv6_header_t *) (_pkbuf_get_ipv6 (pkbuf)))
+
+static inline uint8_t *
+_pkbuf_get_tcp (const hicn_packet_buffer_t *pkbuf)
+{
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->tcp;
+ assert (header);
+ return header;
+}
+#define pkbuf_get_tcp(pkbuf) ((_tcp_header_t *) (_pkbuf_get_tcp (pkbuf)))
+
+static inline uint8_t *
+_pkbuf_get_udp (const hicn_packet_buffer_t *pkbuf)
+{
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->udp;
+ assert (header);
+ return header;
+}
+#define pkbuf_get_udp(pkbuf) ((_udp_header_t *) (_pkbuf_get_udp (pkbuf)))
+
+static inline uint8_t *
+_pkbuf_get_icmp (const hicn_packet_buffer_t *pkbuf)
+{
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->icmp;
+ assert (header);
+ return header;
+}
+#define pkbuf_get_icmp(pkbuf) ((_icmp_header_t *) (_pkbuf_get_icmp (pkbuf)))
+
+static inline uint8_t *
+_pkbuf_get_ah (const hicn_packet_buffer_t *pkbuf)
+{
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->ah;
+ assert (header);
+ return header;
+}
+#define pkbuf_get_ah(pkbuf) ((_ah_header_t *) (_pkbuf_get_ah (pkbuf)))
+
+static inline uint8_t *
+_pkbuf_get_new (const hicn_packet_buffer_t *pkbuf)
+{
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->newhdr;
+ assert (header);
+ return header;
+}
+#define pkbuf_get_new(pkbuf) ((_new_header_t *) (_pkbuf_get_new (pkbuf)))
+
+static inline uint8_t *
+pkbuf_get_header (const hicn_packet_buffer_t *pkbuf)
+{
+ uint8_t *header = (uint8_t *) pkbuf + pkbuf->header;
+ assert (header);
+ return header;
+}
+
+static inline void
+pkbuf_set_header (hicn_packet_buffer_t *pkbuf, uint8_t *header)
+{
+ ssize_t offset = header - (uint8_t *) pkbuf;
+ assert (offset < INT64_MAX);
+ assert (offset > INT64_MIN);
+ pkbuf->header = (int64_t) offset;
+}
+
+/*
+ * Packet buffer operations
+ *
+ * A packet buffer can either be initialized either:
+ *
+ * 1) from an empty buffer (packet crafting).
+ *
+ * #define MTU 1500
+ * size_t size = MTU;
+ * u8 buffer[MTU];
+ *
+ * hicn_packet_t pkbuf;
+ * hicn_packet_set_format(&pkbuf, HICN_PACKET_FORMAT_NEW);
+ * hicn_packet_set_buffer(&pkbuf, &buffer, size);
+ * hicn_packet_init_header(&pkbuf, 0);
+ *
+ * An empty (but correct) packet is not available in the buffer, ready to be
+ * modified and/or sent.
+ *
+ * 2) from an existing buffer (packet reception):
+ *
+ * hicn_packet_t pkbuf;
+ * hicn_packet_set_buffer(&pkbuf, &buffer, size);
+ * hicn_packet_analyze(&pkbuf);
+ *
+ * It is then possible to retrieve properties of the packet such as format and
+ * type (interest, data, etc.).
+ *
+ * hicn_packet_get_format(&pkbuf);
+ * hicn_packet_get_type(&pkbuf);
+ *
+ * */
+
+hicn_packet_format_t
+hicn_packet_get_format (const hicn_packet_buffer_t *pkbuf);
+
+void hicn_packet_set_format (hicn_packet_buffer_t *pkbuf,
+ hicn_packet_format_t format);
+
+hicn_packet_type_t hicn_packet_get_type (const hicn_packet_buffer_t *pkbuf);
+void hicn_packet_set_type (hicn_packet_buffer_t *pkbuf,
+ hicn_packet_type_t type);
+
+bool hicn_packet_is_interest (const hicn_packet_buffer_t *pkbuf);
+
+bool hicn_packet_is_data (const hicn_packet_buffer_t *pkbuf);
+
+bool hicn_packet_is_undefined (const hicn_packet_buffer_t *pkbuf);
+
+/**
+ * @brief Initialize the buffer from packet buffer metadata (builds a valid
+ * packet).
+ * @param [in] pkbuf - hICN packet buffer
+ * @return hICN error code
+ *
+ * Packet type, format, and a buffer are required.
+ */
+int hicn_packet_init_header (hicn_packet_buffer_t *pkbuf,
+ size_t additional_header_size);
+
+/**
+ * @brief Reset information stored in the packet header.
+ * @param [in] pkbuf - hICN packet buffer
+ * @return hICN error code
+ */
+int hicn_packet_reset (hicn_packet_buffer_t *pkbuf);
+
+/**
+ * @brief Analyze buffer to populate metadata in packet buffer.
+ * @param [in] pkbuf - hICN packet buffer
+ * @return hICN error code
+ */
+int hicn_packet_analyze (hicn_packet_buffer_t *pkbuf);
+
+/**
+ * @brief Initialize hicn packet storage space with a buffer
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] buffer - Packet storage buffer
+ * @param [in] analyze - Flag indicating whether to analyze the buffer
+ * content to populate packet format, header's offsets, etc.
+ * @return hICN error code
+ */
+int hicn_packet_set_buffer (hicn_packet_buffer_t *pkbuf, u8 *buffer,
+ uint16_t buffer_size, uint16_t len);
+
+/**
+ * @brief Retrieve the storage buffer.
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] buffer - Packet buffer
+ * @param [out] buffer_size - Packet buffer size
+ * @return Pointer to storage buffer (this only returns the pointer; no copy is
+ * made)
+ */
+int hicn_packet_get_buffer (const hicn_packet_buffer_t *pkbuf, u8 **buffer,
+ uint16_t *buffer_size, uint16_t *len);
+
+/**
+ * @brief Retrieve the packet length
+ * @param [in] pkbuf - hICN packet buffer
+ * @return Length of the stored packet
+ */
+size_t hicn_packet_get_len (const hicn_packet_buffer_t *pkbuf);
+
+/**
+ * @brief Set the packet length
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] len - hICN packet length
+ * @return None
+ */
+int hicn_packet_set_len (hicn_packet_buffer_t *pkbuf, size_t len);
+
+/**
+ * @brief Return total length of hicn headers (before payload)
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] len - Total headers length
+ * @return Headers' len
+ */
+int hicn_packet_get_header_len (const hicn_packet_buffer_t *pkbuf,
+ size_t *len);
+
+/**
+ * @brief Return the length of hICN payload in the packet.
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] len - hICN payload length
+ * @return Payload len
+ */
+int hicn_packet_get_payload_len (const hicn_packet_buffer_t *pkbuf,
+ size_t *len);
+
+/**
+ * @brief Sets the payload of a packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @param [in] payload - payload to set
+ * @param [in] payload_length - size of the payload to set
+ * @return hICN error code
+ *
+ * NOTE:
+ * - The buffer holding payload is assumed sufficiently large
+ * - This function updates header fields with the new length, but no checksum.
+ */
+int hicn_packet_set_payload (const hicn_packet_buffer_t *pkbuf,
+ const u8 *payload, u16 payload_length);
+
+/**
+ * @brief Retrieves the payload of a packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] payload - pointer to buffer for storing the result
+ * @param [out] payload_length - size of the retreived payload
+ * @param [in] hard_copy - Flag : if true (eg. 1), a copy of the payload is
+ * made into the payload buffer, otherwise (0) the pointer is changed to point
+ * to the payload offset in the packet.
+ * @return hICN error code
+ *
+ * NOTE:
+ * - The buffer holding payload is assumed sufficiently large
+ */
+int hicn_packet_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
+ size_t *payload_size, bool hard_copy);
+
+/* Header fields manipulation */
+
+/**
+ * @brief Return total length of hicn headers (but signature payload)
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] header_length - Total length of headers
+ * @return hICN error code
+ */
+int hicn_packet_get_header_length_from_format (hicn_packet_format_t format,
+ size_t *header_length);
+
+/**
+ * @brief Sets payload length
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @param [in] payload_length - payload length
+ * @return hICN error code
+ */
+int hicn_packet_set_payload_length (const hicn_packet_buffer_t *pkbuf,
+ const size_t payload_length);
+
+/**
+ * @brief Compare two hICN packets
+ * @param [in] packet_1 - First packet
+ * @param [in] packet_2 - Second packet
+ * @return 0 if both packets are considered equal, any other value otherwise.
+ */
+int hicn_packet_compare (const hicn_packet_buffer_t *pkbuf11,
+ const hicn_packet_buffer_t *pkbuf22);
+
+/**
+ * @brief Retrieve the name of an interest/data packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] name - name holding the result
+ * @return hICN error code
+ */
+int hicn_packet_get_name (const hicn_packet_buffer_t *pkbuf,
+ hicn_name_t *name);
+
+/**
+ * @brief Sets the name of an interest/data packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @param [in] name - name to set into packet
+ * @return hICN error code
+ */
+int hicn_packet_set_name (const hicn_packet_buffer_t *pkbuf,
+ const hicn_name_t *name);
+
+/**
+ * @brief Retrieve the locator of an interest / data packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] ip_address - retrieved locator
+ * @return hICN error code
+ */
+int hicn_packet_get_locator (const hicn_packet_buffer_t *pkbuf,
+ hicn_ip_address_t *prefix);
+
+/**
+ * @brief Sets the locator of an interest / data packet
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @param [out] ip_address - retrieved locator
+ * @return hICN error code
+ */
+int hicn_packet_set_locator (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *prefix);
+
+int hicn_packet_save_header (const hicn_packet_buffer_t *pkbuf, u8 *header,
+ size_t *header_len, bool copy_ah);
+
+int hicn_packet_load_header (const hicn_packet_buffer_t *pkbuf,
+ const u8 *header, size_t header_len);
+
+int hicn_packet_get_lifetime (const hicn_packet_buffer_t *pkbuf,
+ u32 *lifetime);
+int hicn_packet_set_lifetime (const hicn_packet_buffer_t *pkbuf, u32 lifetime);
+
+/* Interest */
+int hicn_interest_get_name (const hicn_packet_buffer_t *pkbuf,
+ hicn_name_t *name);
+int hicn_interest_set_name (const hicn_packet_buffer_t *pkbuf,
+ const hicn_name_t *name);
+int hicn_interest_get_locator (const hicn_packet_buffer_t *pkbuf,
+ hicn_ip_address_t *prefix);
+int hicn_interest_set_locator (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *prefix);
+int hicn_interest_compare (const hicn_packet_buffer_t *pkbuf11,
+ const hicn_packet_buffer_t *pkbuf2);
+int hicn_interest_set_lifetime (const hicn_packet_buffer_t *pkbuf,
+ u32 lifetime);
+int hicn_interest_get_lifetime (const hicn_packet_buffer_t *pkbuf,
+ u32 *lifetime);
+int hicn_interest_get_header_length (const hicn_packet_buffer_t *pkbuf,
+ size_t *header_length);
+int hicn_interest_get_payload_length (const hicn_packet_buffer_t *pkbuf,
+ size_t *payload_length);
+int hicn_interest_set_payload (const hicn_packet_buffer_t *pkbuf,
+ const u8 *payload, size_t payload_length);
+int hicn_interest_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
+ size_t *payload_size, bool hard_copy);
+int hicn_interest_reset_for_hash (hicn_packet_buffer_t *pkbuf);
+
+/* Data */
+
+int hicn_data_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name);
+int hicn_data_set_name (const hicn_packet_buffer_t *pkbuf,
+ const hicn_name_t *name);
+int hicn_data_get_locator (const hicn_packet_buffer_t *pkbuf,
+ hicn_ip_address_t *prefix);
+int hicn_data_set_locator (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *prefix);
+int hicn_data_compare (const hicn_packet_buffer_t *pkbuf11,
+ const hicn_packet_buffer_t *pkbuf22);
+int hicn_data_get_expiry_time (const hicn_packet_buffer_t *pkbuf,
+ u32 *expiry_time);
+int hicn_data_set_expiry_time (const hicn_packet_buffer_t *pkbuf,
+ u32 expiry_time);
+int hicn_data_get_header_length (const hicn_packet_buffer_t *pkbuf,
+ size_t *header_length);
+int hicn_data_get_payload_length (const hicn_packet_buffer_t *pkbuf,
+ size_t *payload_length);
+
+/* Path label */
+
+/**
+ * @brief Returns the path label from a data packet
+ * @param [in] pkbuf - packet buffer
+ * @param [in] hdr - packet header
+ * @param [in] path_label - pointer in which to store the path label value
+ * @return hICN error code
+ */
+int hicn_data_get_path_label (const hicn_packet_buffer_t *pkbufdr,
+ hicn_path_label_t *path_label);
+
+/**
+ * @brief Returns the path label from a packet
+ * @param [in] pkbuf - packet buffer
+ * @param [in] hdr - packet header
+ * @param [in] path_label - pointer in which to store the path label value
+ * @return hICN error code
+ */
+int hicn_get_path_label (const hicn_packet_buffer_t *pkbufdr,
+ hicn_path_label_t *path_label);
+
+int hicn_data_set_path_label (const hicn_packet_buffer_t *pkbuf,
+ hicn_path_label_t path_label);
+
+/* Data specific flags */
+
+int hicn_packet_get_payload_type (const hicn_packet_buffer_t *pkbuf,
+
+ hicn_payload_type_t *payload_type);
+int hicn_packet_set_payload_type (const hicn_packet_buffer_t *pkbuf,
+
+ const hicn_payload_type_t payload_type);
+
+int hicn_data_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
+ size_t *payload_size, bool hard_copy);
+int hicn_data_set_payload (const hicn_packet_buffer_t *pkbuf,
+ const u8 *payload, size_t payload_length);
+int hicn_data_get_payload_type (hicn_payload_type_t *payload_type);
+int hicn_data_set_payload_type (hicn_payload_type_t payload_type);
+int hicn_data_reset_for_hash (hicn_packet_buffer_t *pkbuf);
+int hicn_data_is_last (const hicn_packet_buffer_t *pkbuf, int *is_last);
+int hicn_data_set_last (const hicn_packet_buffer_t *pkbuf);
+
+/* Security */
+
+/**
+ * @brief Retrieves the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] bytes - Retrieved signature size
+ * @return hICN error code
+ */
+int hicn_packet_get_signature_size (const hicn_packet_buffer_t *pkbuf,
+ size_t *bytes);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [in] bytes - Retrieved signature size
+ * @return hICN error code
+ */
+int hicn_packet_set_signature_size (const hicn_packet_buffer_t *pkbuf,
+ size_t bytes);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [in] signature_timestamp - Signature timestamp to set
+ * @return hICN error code
+ */
+int hicn_packet_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf,
+ uint64_t signature_timestamp);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] signature_timestamp - Retrieved signature timestamp
+ * @return hICN error code
+ */
+int hicn_packet_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf,
+ uint64_t *signature_timestamp);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [in] validation_algorithm - Validation algorithm to set
+ * @return hICN error code
+ */
+int hicn_packet_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf,
+ uint8_t validation_algorithm);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] validation_algorithm - Retrieved validation algorithm
+ * @return hICN error code
+ */
+int hicn_packet_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf,
+ uint8_t *validation_algorithm);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [in] key_id - Key id to set
+ * @param [in] key_len - Key length
+ * @return hICN error code
+ */
+int hicn_packet_set_key_id (const hicn_packet_buffer_t *pkbuf, uint8_t *key_id,
+ size_t key_len);
+
+/**
+ * @brief Sets the signature size
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in] packet - packet header
+ * @param [out] key_id - Retrieved key id
+ * @return hICN error code
+ */
+int hicn_packet_get_key_id (const hicn_packet_buffer_t *pkbuf,
+ uint8_t **key_id, uint8_t *key_id_length);
+
+int hicn_packet_get_signature (const hicn_packet_buffer_t *pkbuf,
+ uint8_t **sign_buf);
+
+int hicn_packet_get_signature_padding (const hicn_packet_buffer_t *pkbuf,
+ size_t *bytes);
+int hicn_packet_set_signature_padding (const hicn_packet_buffer_t *pkbuf,
+ size_t bytes);
+
+/* Checksums */
+
+/**
+ * @brief Update checksums in packet headers
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @return hICN error code
+ */
+int hicn_packet_compute_checksum (const hicn_packet_buffer_t *pkbuf);
+
+/**
+ * @brief compute the checksum of the packet header, adding init_sum to the
+ * final value
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @param [in] init_sum - value to add to the final checksum
+ * @return hICN error code
+ */
+int hicn_packet_compute_header_checksum (const hicn_packet_buffer_t *pkbuf,
+ u16 init_sum);
+
+/**
+ * @brief Verify checksums in packet headers
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [in,out] packet - packet header
+ * @return hICN error code
+ */
+int hicn_packet_check_integrity_no_payload (const hicn_packet_buffer_t *pkbuf,
+ u16 init_sum);
+
+/**
+ * @brief Returns the packet TTL
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] hops - Pointer to the variable receiving the TTL value
+ * @return hICN error code
+ */
+int hicn_packet_get_ttl (const hicn_packet_buffer_t *pkbuf, 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 hicn_packet_set_ttl (const hicn_packet_buffer_t *pkbuf, u8 hops);
+
+/**
+ * @brief Returns the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] port - Pointer to the variable that will receive the port
+ * number
+ * @return hICN error code
+ */
+int hicn_packet_get_src_port (const hicn_packet_buffer_t *pkbuf, u16 *port);
+
+/**
+ * @brief Sets the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] port - The port number to set
+ * @return hICN error code
+ */
+int hicn_packet_set_src_port (const hicn_packet_buffer_t *pkbuf, u16 port);
+
+/**
+ * @brief Returns the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] port - Pointer to the variable that will receive the port
+ * number
+ * @return hICN error code
+ */
+int hicn_packet_get_dst_port (const hicn_packet_buffer_t *pkbuf, u16 *port);
+
+/**
+ * @brief Sets the packet source port
+ * @param [in] pkbuf - hICN packet buffer
+ * @param [out] port - The port number to set
+ * @return hICN error code
+ */
+int hicn_packet_set_dst_port (const hicn_packet_buffer_t *pkbuf, u16 port);
+
+int hicn_interest_rewrite (const hicn_packet_buffer_t *pkbuf,
+ const hicn_ip_address_t *addr_new,
+ hicn_ip_address_t *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);
+
+#endif /* HICN_PACKET_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/policy.h b/lib/includes/hicn/policy.h
index f39fa9272..50b771537 100644
--- a/lib/includes/hicn/policy.h
+++ b/lib/includes/hicn/policy.h
@@ -151,7 +151,7 @@ policy_state_t policy_state_from_str (const char *str);
/* POLICY TAG STATE */
-typedef struct
+typedef struct __attribute__ ((packed, aligned (1)))
{
policy_state_t state;
uint8_t disabled;
diff --git a/lib/includes/hicn/protocol/icmprd.h b/lib/includes/hicn/protocol/icmprd.h
index 897e7969e..17088c22a 100644
--- a/lib/includes/hicn/protocol/icmprd.h
+++ b/lib/includes/hicn/protocol/icmprd.h
@@ -33,7 +33,7 @@ typedef struct
u8 type;
u8 code;
u16 csum;
- ip4_address_t ip;
+ ipv4_address_t ip;
_ipv4_header_t iph;
u8 data[64];
} _icmprd4_header_t;
@@ -53,8 +53,8 @@ typedef struct
u8 code;
u16 csum;
u32 res;
- ip6_address_t tgt;
- ip6_address_t dst;
+ ipv6_address_t tgt;
+ ipv6_address_t dst;
} _icmprd_header_t;
#define ICMPRD_HDRLEN sizeof (_icmprd_header_t)
diff --git a/lib/includes/hicn/protocol/ipv4.h b/lib/includes/hicn/protocol/ipv4.h
index 44e95c1e3..89435b516 100644
--- a/lib/includes/hicn/protocol/ipv4.h
+++ b/lib/includes/hicn/protocol/ipv4.h
@@ -54,8 +54,8 @@ typedef struct
u8 ttl;
u8 protocol;
u16 csum;
- ip4_address_t saddr;
- ip4_address_t daddr;
+ ipv4_address_t saddr;
+ ipv4_address_t daddr;
} _ipv4_header_t;
#define ipv4_header_bytes(ipv4_header) \
@@ -72,8 +72,8 @@ static_assert (EXPECTED_IPV4_HDRLEN == IPV4_HDRLEN,
typedef struct
{
- ip4_address_t ip_src;
- ip4_address_t ip_dst;
+ ipv4_address_t ip_src;
+ ipv4_address_t ip_dst;
u8 zero;
u8 protocol;
u16 size;
diff --git a/lib/includes/hicn/protocol/ipv6.h b/lib/includes/hicn/protocol/ipv6.h
index 86301e7d1..6e8e30af3 100644
--- a/lib/includes/hicn/protocol/ipv6.h
+++ b/lib/includes/hicn/protocol/ipv6.h
@@ -42,8 +42,8 @@ typedef struct
u8 vfc; /* 4 bits version, top 4 bits class */
};
#endif
- ip6_address_t saddr; /* source address */
- ip6_address_t daddr; /* destination address */
+ ipv6_address_t saddr; /* source address */
+ ipv6_address_t daddr; /* destination address */
} _ipv6_header_t;
#define IPV6_HDRLEN sizeof (_ipv6_header_t)
@@ -57,8 +57,8 @@ static_assert (EXPECTED_IPV6_HDRLEN == IPV6_HDRLEN,
typedef struct
{
- ip6_address_t ip_src;
- ip6_address_t ip_dst;
+ ipv6_address_t ip_src;
+ ipv6_address_t ip_dst;
u32 size;
u16 zeros;
u8 zero;
diff --git a/lib/includes/hicn/protocol/new.h b/lib/includes/hicn/protocol/new.h
index 47f7758d2..e688bef21 100644
--- a/lib/includes/hicn/protocol/new.h
+++ b/lib/includes/hicn/protocol/new.h
@@ -34,7 +34,7 @@ typedef struct
u8 flags;
u16 payload_length;
u32 lifetime;
- ip_address_t prefix;
+ hicn_ip_address_t prefix;
u32 suffix;
u32 path_label;
} _new_header_t;
diff --git a/lib/includes/hicn/util/bitmap.h b/lib/includes/hicn/util/bitmap.h
index 11eb7870b..15d47ac61 100644
--- a/lib/includes/hicn/util/bitmap.h
+++ b/lib/includes/hicn/util/bitmap.h
@@ -24,17 +24,26 @@
#define UTIL_BITMAP_H
#include <assert.h>
+#include <stdio.h>
#include <string.h>
#include <sys/param.h> // MIN, MAX
-#include <hicn/util/log.h>
-
#include <hicn/common.h>
#include <hicn/util/vector.h>
-typedef uint_fast32_t bitmap_t;
+typedef hicn_uword bitmap_t;
+
+#define WORD_WIDTH (sizeof (bitmap_t) * 8)
+#define WORD_WIDTH (sizeof (bitmap_t) * 8)
#define BITMAP_WIDTH(bitmap) (sizeof ((bitmap)[0]) * 8)
+#define BITMAP_INVALID_INDEX ((uint32_t) (~0))
+
+static inline int
+get_lowest_set_bit_index (hicn_uword w)
+{
+ return hicn_uword_bits > 32 ? __builtin_ctzll (w) : __builtin_ctz (w);
+}
/**
* @brief Allocate and initialize a bitmap
@@ -79,13 +88,27 @@ bitmap_ensure_pos (bitmap_t **bitmap, off_t pos)
* @param[in] i The bit position.
*/
static inline int
-bitmap_get (const bitmap_t *bitmap, off_t i)
+_bitmap_get (const bitmap_t *bitmap, off_t i)
{
size_t offset = i / BITMAP_WIDTH (bitmap);
assert (offset < bitmap_get_alloc_size (bitmap));
size_t pos = i % BITMAP_WIDTH (bitmap);
- size_t shift = BITMAP_WIDTH (bitmap) - pos - 1;
- return (bitmap[offset] >> shift) & 1;
+ return (bitmap[offset] >> pos) & 1;
+}
+
+/**
+ * @brief Retrieve the state of the i-th bit in the bitmap.
+ * Does not sanity check the position.
+ *
+ * @param[in] bitmap The bitmap to access.
+ * @param[in] i The bit position.
+ */
+static inline int
+_bitmap_get_no_check (const bitmap_t *bitmap, off_t i)
+{
+ size_t offset = i / BITMAP_WIDTH (bitmap);
+ size_t pos = i % BITMAP_WIDTH (bitmap);
+ return (bitmap[offset] >> pos) & 1;
}
/*
@@ -96,8 +119,13 @@ bitmap_get (const bitmap_t *bitmap, off_t i)
*
* @return bool
*/
-#define bitmap_is_set(bitmap, i) (bitmap_get ((bitmap), (i)) == 1)
-#define bitmap_is_unset(bitmap, i) (bitmap_get ((bitmap), (i)) == 0)
+#define bitmap_is_set(bitmap, i) (_bitmap_get ((bitmap), (i)) == 1)
+#define bitmap_is_unset(bitmap, i) (_bitmap_get ((bitmap), (i)) == 0)
+
+#define bitmap_is_set_no_check(bitmap, i) \
+ (_bitmap_get_no_check ((bitmap), (i)) == 1)
+#define bitmap_is_unset_no_check(bitmap, i) \
+ (_bitmap_get_no_check ((bitmap), (i)) == 0)
/*
* @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap.
@@ -107,7 +135,9 @@ bitmap_get (const bitmap_t *bitmap, off_t i)
*
* @return bool
*/
-#define bitmap_set(bitmap, i) _bitmap_set ((bitmap_t **) &bitmap, i)
+#define bitmap_set(bitmap, i) _bitmap_set ((bitmap_t **) &bitmap, i, 1)
+#define bitmap_set_no_check(bitmap, i) \
+ _bitmap_set ((bitmap_t **) &bitmap, i, 0)
/*
* @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap
@@ -119,29 +149,30 @@ bitmap_get (const bitmap_t *bitmap, off_t i)
* @return bool
*/
static inline int
-_bitmap_set (bitmap_t **bitmap_ptr, off_t i)
+_bitmap_set (bitmap_t **bitmap_ptr, off_t i, int check)
{
- if (bitmap_ensure_pos (bitmap_ptr, i) < 0)
+ if (check && bitmap_ensure_pos (bitmap_ptr, i) < 0)
return -1;
bitmap_t *bitmap = *bitmap_ptr;
size_t offset = i / BITMAP_WIDTH (bitmap);
size_t pos = i % BITMAP_WIDTH (bitmap);
- size_t shift = BITMAP_WIDTH (bitmap) - pos - 1;
- bitmap[offset] |= (bitmap_t) 1 << shift;
+ bitmap[offset] |= (bitmap_t) 1 << pos;
return 0;
}
+#define bitmap_unset(bitmap, i) _bitmap_unset (bitmap, i, 1)
+#define bitmap_unset_no_check(bitmap, i) _bitmap_unset (bitmap, i, 0)
+
static inline int
-bitmap_unset (bitmap_t *bitmap, off_t i)
+_bitmap_unset (bitmap_t *bitmap, off_t i, int check)
{
- if (bitmap_ensure_pos (&bitmap, i) < 0)
+ if (check && bitmap_ensure_pos (&bitmap, i) < 0)
return -1;
size_t offset = i / BITMAP_WIDTH (bitmap);
size_t pos = i % BITMAP_WIDTH (bitmap);
- size_t shift = BITMAP_WIDTH (bitmap) - pos - 1;
- bitmap[offset] &= ~(1ul << shift);
+ bitmap[offset] &= ~(1ul << pos);
return 0;
}
@@ -201,7 +232,6 @@ bitmap_set_range (bitmap_t *bitmap, off_t from, off_t to)
return 0;
END:
- ERROR ("Error setting bitmap range\n");
return -1;
}
@@ -209,4 +239,88 @@ END:
#define bitmap_free(bitmap) vector_free (bitmap)
+static inline hicn_uword
+bitmap_next_set_no_check (const bitmap_t *bitmap, hicn_uword i, size_t length)
+{
+ hicn_uword pos = i / WORD_WIDTH;
+ hicn_uword offset = i % WORD_WIDTH;
+ hicn_uword tmp;
+ hicn_uword mask = ~((1ULL << offset) - 1);
+
+ if (pos < length)
+ {
+ // This will zeroes all bits < i
+ tmp = bitmap[pos] & mask;
+ if (tmp)
+ return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+
+ for (pos += 1; pos < length; pos++)
+ {
+ tmp = bitmap[pos];
+ if (tmp)
+ return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+ }
+ }
+
+ return BITMAP_INVALID_INDEX;
+}
+
+static inline hicn_uword
+bitmap_next_set (const bitmap_t *bitmap, hicn_uword i)
+{
+ return bitmap_next_set_no_check (bitmap, i, vector_get_alloc_size (bitmap));
+}
+
+static inline hicn_uword
+bitmap_next_unset_no_check (const bitmap_t *bitmap, hicn_uword i,
+ size_t length)
+{
+ hicn_uword pos = i / WORD_WIDTH;
+ hicn_uword offset = i % WORD_WIDTH;
+ hicn_uword tmp;
+ hicn_uword mask = ~((1ULL << offset) - 1);
+
+ if (pos < length)
+ {
+ // This will zeroes all bits < i
+ tmp = ~bitmap[pos] & mask;
+ if (tmp)
+ return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+
+ for (pos += 1; pos < length; pos++)
+ {
+ tmp = ~bitmap[pos];
+ if (tmp)
+ return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+ }
+ }
+ return BITMAP_INVALID_INDEX;
+}
+
+static inline hicn_uword
+bitmap_next_unset (const bitmap_t *bitmap, hicn_uword i)
+{
+ return bitmap_next_unset_no_check (bitmap, i,
+ vector_get_alloc_size (bitmap));
+}
+
+#define bitmap_first_set(bitmap) bitmap_next_set (bitmap, 0)
+#define bitmap_first_set_no_check(bitmap, size) \
+ bitmap_next_set_no_checks (bitmap, 0, size)
+
+#define bitmap_first_unset(bitmap) bitmap_next_unset (bitmap, 0)
+#define bitmap_first_unset_no_check(bitmap, size) \
+ bitmap_next_unset_no_checks (bitmap, 0, size)
+
+static inline void
+bitmap_print (const bitmap_t *bitmap, size_t n_words)
+{
+ for (size_t word = 0; word < n_words; word++)
+ {
+ for (int bit = sizeof (hicn_uword) - 1; bit >= 0; bit--)
+ (bitmap_is_set_no_check (&bitmap[word], bit)) ? printf ("1") :
+ printf ("0");
+ }
+}
+
#endif /* UTIL_BITMAP_H */
diff --git a/lib/includes/hicn/util/hash.h b/lib/includes/hicn/util/hash.h
index ded8fc370..8dbe0d680 100644
--- a/lib/includes/hicn/util/hash.h
+++ b/lib/includes/hicn/util/hash.h
@@ -28,6 +28,7 @@
#define UTIL_HASH_H
#include <stdint.h>
+#include <stddef.h> // size_t
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
__BYTE_ORDER == __LITTLE_ENDIAN) || \
diff --git a/lib/includes/hicn/util/ip_address.h b/lib/includes/hicn/util/ip_address.h
index 89a4c11e0..55d5f5fc3 100644
--- a/lib/includes/hicn/util/ip_address.h
+++ b/lib/includes/hicn/util/ip_address.h
@@ -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:
@@ -32,10 +32,11 @@
#endif
#include <errno.h>
+#include <assert.h>
#ifndef _WIN32
#include <netinet/in.h> // struct sockadd
-#include <arpa/inet.h>
-#include <netdb.h> // struct addrinfo
+#include <arpa/inet.h> // inet_ntop
+#include <netdb.h> // struct addrinfo
#endif
#include <stdbool.h>
#include <stdlib.h>
@@ -61,11 +62,10 @@
#endif
//#define INET_MAX_ADDRSTRLEN INET6_ADDRSTRLEN
-#define IP_MAX_ADDR_LEN IPV6_ADDR_LEN
+#define IP_ADDRESS_MAX_LEN IPV6_ADDR_LEN
#define DUMMY_PORT 1234
-#ifndef HICN_VPP_PLUGIN
typedef union
{
struct in_addr as_inaddr;
@@ -73,9 +73,11 @@ typedef union
u8 as_u8[4];
u16 as_u16[2];
u32 as_u32;
-} ip4_address_t;
+} ipv4_address_t;
-typedef union
+static_assert (sizeof (ipv4_address_t) == 4, "");
+
+typedef union __attribute__ ((__packed__))
{
struct in6_addr as_in6addr;
u8 buffer[16];
@@ -83,16 +85,24 @@ typedef union
u16 as_u16[8];
u32 as_u32[4];
u64 as_u64[2];
-} ip6_address_t;
+} ipv6_address_t;
+
+static_assert (sizeof (ipv6_address_t) == 16, "");
+
+#ifdef HICN_VPP_PLUGIN
+#include <vnet/ip/ip46_address.h>
+static_assert (sizeof (ipv4_address_t) == sizeof (ip4_address_t), "");
+static_assert (sizeof (ipv6_address_t) == sizeof (ip6_address_t), "");
+#endif
typedef union
{
struct
{
u32 pad[3];
- ip4_address_t v4;
+ ipv4_address_t v4;
};
- ip6_address_t v6;
+ ipv6_address_t v6;
#if 0 /* removed as prone to error due to IPv4 padding */
u8 buffer[IP_MAX_ADDR_LEN];
u8 as_u8[IP_MAX_ADDR_LEN];
@@ -100,28 +110,14 @@ typedef union
u32 as_u32[IP_MAX_ADDR_LEN >> 2];
u64 as_u64[IP_MAX_ADDR_LEN >> 3];
#endif
-} ip_address_t;
-
-#else
-
-#include <vnet/ip/ip4_packet.h> // ip4_address_t
-#include <vnet/ip/ip6_packet.h> // ip6_address_t
-
-#if __GNUC__ >= 9
-#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
-#endif
-
-#include <vnet/ip/ip46_address.h>
-
-#if __GNUC__ >= 9
-#pragma GCC diagnostic pop
-#endif
-
-typedef ip46_address_t ip_address_t;
-
+#ifdef HICN_VPP_PLUGIN
+ ip46_address_t as_ip46;
#endif /* HICN_VPP_PLUGIN */
+} hicn_ip_address_t;
+
+static_assert (sizeof (hicn_ip_address_t) == 16, "");
-#define ip_address_is_v4(ip) \
+#define hicn_ip_address_is_v4(ip) \
(((ip)->pad[0] | (ip)->pad[1] | (ip)->pad[2]) == 0)
#define MAXSZ_IP4_ADDRESS_ INET_ADDRSTRLEN - 1
@@ -131,24 +127,26 @@ typedef ip46_address_t ip_address_t;
#define MAXSZ_IP6_ADDRESS MAXSZ_IP6_ADDRESS_ + 1
#define MAXSZ_IP_ADDRESS MAXSZ_IP_ADDRESS_ + 1
+#define IP_ADDRESS_V4_OFFSET_LEN 12
+
typedef struct
{
int family;
- ip_address_t address;
+ hicn_ip_address_t address;
u8 len;
-} ip_prefix_t;
+} hicn_ip_prefix_t;
#define MAXSZ_IP_PREFIX_ MAXSZ_IP_ADDRESS_ + 1 + 3
#define MAXSZ_IP_PREFIX MAXSZ_IP_PREFIX_ + 1
-extern const ip_address_t IPV4_LOOPBACK;
-extern const ip_address_t IPV6_LOOPBACK;
-extern const ip_address_t IPV4_ANY;
-extern const ip_address_t IPV6_ANY;
+extern const hicn_ip_address_t IPV4_LOOPBACK;
+extern const hicn_ip_address_t IPV6_LOOPBACK;
+extern const hicn_ip_address_t IPV4_ANY;
+extern const hicn_ip_address_t IPV6_ANY;
-extern const ip4_address_t IP4_ADDRESS_EMPTY;
-extern const ip6_address_t IP6_ADDRESS_EMPTY;
-extern const ip_address_t IP_ADDRESS_EMPTY;
+extern const ipv4_address_t IP4_ADDRESS_EMPTY;
+extern const ipv6_address_t IP6_ADDRESS_EMPTY;
+extern const hicn_ip_address_t IP_ADDRESS_EMPTY;
#define IP_ANY(family) (family == AF_INET) ? IPV4_ANY : IPV6_ANY
@@ -161,32 +159,52 @@ extern const ip_address_t IP_ADDRESS_EMPTY;
#define IS_VALID_FAMILY(x) ((x == AF_INET) || (x == AF_INET6))
/* IP address */
-
-int ip_address_get_family (const char *ip_address);
-int ip_address_len (int family);
-const u8 *ip_address_get_buffer (const ip_address_t *ip_address, int family);
-int ip_address_ntop (const ip_address_t *ip_address, char *dst,
- const size_t len, int family);
-int 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);
-int ip_address_to_sockaddr (const ip_address_t *ip_address,
- struct sockaddr *sa, int family);
-int ip_address_cmp (const ip_address_t *ip1, const ip_address_t *ip2,
- int family);
-int ip_address_empty (const ip_address_t *ip);
+int hicn_ip_address_get_family (const hicn_ip_address_t *address);
+int hicn_ip_address_str_get_family (const char *ip_address);
+int hicn_ip_address_len (int family);
+int hicn_ip_address_get_len (const hicn_ip_address_t *ip_address);
+
+int hicn_ip_address_get_len_bits (const hicn_ip_address_t *ip_address);
+const u8 *hicn_ip_address_get_buffer (const hicn_ip_address_t *ip_address,
+ int family);
+int hicn_ip_address_ntop (const hicn_ip_address_t *ip_address, char *dst,
+ const size_t len, int family);
+int hicn_ip_address_pton (const char *ip_address_str,
+ hicn_ip_address_t *ip_address);
+int hicn_ip_address_snprintf (char *s, size_t size,
+ const hicn_ip_address_t *ip_address);
+int hicn_ip_address_to_sockaddr (const hicn_ip_address_t *ip_address,
+ struct sockaddr *sa, int family);
+int hicn_ip_address_cmp (const hicn_ip_address_t *ip1,
+ const hicn_ip_address_t *ip2);
+bool hicn_ip_address_equals (const hicn_ip_address_t *ip1,
+ const hicn_ip_address_t *ip2);
+int hicn_ip_address_empty (const hicn_ip_address_t *ip);
+
+uint8_t hicn_ip_address_get_bit (const hicn_ip_address_t *address,
+ uint8_t pos);
+
+bool hicn_ip_address_match_family (const hicn_ip_address_t *address,
+ int family);
+
+uint32_t hicn_ip_address_get_hash (const hicn_ip_address_t *address);
/* Prefix */
-int ip_prefix_pton (const char *ip_address_str, ip_prefix_t *ip_prefix);
-int 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);
-int ip_prefix_snprintf (char *s, size_t size, const ip_prefix_t *prefix);
-int ip_prefix_len (const ip_prefix_t *prefix);
-bool ip_prefix_empty (const ip_prefix_t *prefix);
-int ip_prefix_to_sockaddr (const ip_prefix_t *prefix, struct sockaddr *sa);
-int ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2);
+int hicn_ip_prefix_pton (const char *ip_address_str,
+ hicn_ip_prefix_t *hicn_ip_prefix);
+int hicn_ip_prefix_ntop_short (const hicn_ip_prefix_t *hicn_ip_prefix,
+ char *dst, size_t size);
+int hicn_ip_prefix_ntop (const hicn_ip_prefix_t *hicn_ip_prefix, char *dst,
+ size_t size);
+int hicn_ip_prefix_snprintf (char *s, size_t size,
+ const hicn_ip_prefix_t *prefix);
+int hicn_ip_prefix_len (const hicn_ip_prefix_t *prefix);
+bool hicn_ip_prefix_empty (const hicn_ip_prefix_t *prefix);
+int hicn_ip_prefix_to_sockaddr (const hicn_ip_prefix_t *prefix,
+ struct sockaddr *sa);
+int hicn_ip_prefix_cmp (const hicn_ip_prefix_t *prefix1,
+ const hicn_ip_prefix_t *prefix2);
/* URL */
@@ -200,7 +218,7 @@ int ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2);
#define MAXSZ_URL6 MAXSZ_URL6_ + NULLTERM
#define MAXSZ_URL MAXSZ_URL_ + NULLTERM
-int url_snprintf (char *s, size_t size, int family,
- const ip_address_t *ip_address, u16 port);
+int url_snprintf (char *s, size_t size, const hicn_ip_address_t *ip_address,
+ u16 port);
#endif /* UTIL_IP_ADDRESS_H */
diff --git a/lib/includes/hicn/util/pool.h b/lib/includes/hicn/util/pool.h
index 7488e08fd..b8acadc44 100644
--- a/lib/includes/hicn/util/pool.h
+++ b/lib/includes/hicn/util/pool.h
@@ -234,6 +234,26 @@ bool _pool_validate_id (void **pool_ptr, off_t id);
} \
while (0)
+#define pool_enumerate_typed(pool, i, TYPE, ELTP, BODY) \
+ do \
+ { \
+ pool_hdr_t *_pool_var (ph) = pool_hdr (pool); \
+ bitmap_t *_pool_var (fb) = _pool_var (ph)->free_bitmap; \
+ TYPE ELTP = NULL; \
+ for ((i) = 0; (i) < _pool_var (ph)->alloc_size; (i)++) \
+ { \
+ if (bitmap_is_set (_pool_var (fb), (i))) \
+ continue; \
+ ELTP = (pool) + (i); \
+ do \
+ { \
+ BODY; \
+ } \
+ while (0); \
+ } \
+ } \
+ while (0)
+
/**
* @brief Iterate over elements in a pool.
*
@@ -256,6 +276,14 @@ bool _pool_validate_id (void **pool_ptr, off_t id);
#define pool_get_alloc_size(pool) pool_hdr (pool)->alloc_size
+#define pool_foreach_typed(pool, TYPE, ELTP, BODY) \
+ do \
+ { \
+ unsigned _pool_var (i); \
+ pool_enumerate_typed ((pool), _pool_var (i), TYPE, ELTP, BODY); \
+ } \
+ while (0)
+
#ifdef WITH_TESTS
#define pool_get_free_indices(pool) pool_hdr (pool)->free_indices
#define pool_get_free_bitmap(pool) pool_hdr (pool)->free_bitmap
diff --git a/lib/includes/hicn/util/sstrncpy.h b/lib/includes/hicn/util/sstrncpy.h
index b316201be..81427be6b 100644
--- a/lib/includes/hicn/util/sstrncpy.h
+++ b/lib/includes/hicn/util/sstrncpy.h
@@ -16,7 +16,10 @@
#ifndef UTIL_SSTRNCPY_H
#define UTIL_SSTRNCPY_H
+#ifndef __STDC_WANT_LIB_EXT1__
#define __STDC_WANT_LIB_EXT1__ 1
+#endif
+
#include <string.h>
#ifdef __STDC_LIB_EXT1__
@@ -30,6 +33,9 @@
typedef int errno_t;
#define EOK 0
+#ifndef HICN_VPP_PLUGIN
+/* This function is already defined in vppinfra/string.h */
+
/**
* @brief This function assures a null byte at the end of the buffer.
*/
@@ -63,6 +69,7 @@ strnlen_s (const char *s, size_t maxlen)
return strnlen (s, maxlen);
}
+#endif /* HICN_VPP_PLUGIN */
#endif /* __STDC_LIB_EXT1__ */
#endif /* UTIL_SSTRNCPY_H */
diff --git a/lib/includes/hicn/util/types.h b/lib/includes/hicn/util/types.h
index 50c5362d3..c9cc878cf 100644
--- a/lib/includes/hicn/util/types.h
+++ b/lib/includes/hicn/util/types.h
@@ -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:
@@ -19,11 +19,46 @@
#include <hicn/util/windows/windows_Utils.h>
#endif
+/* Standard types. */
+#include <stdint.h>
+
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+typedef double f64;
+typedef float f32;
+
+/* Architecture-dependent uword size */
+#if INTPTR_MAX == INT64_MAX
+#define hicn_log2_uword_bits 6
+#elif INTPTR_MAX == INT32_MAX
+#define hicn_log2_uword_bits 5
+#else
+#error "Impossible to detect architecture"
+#endif
+
+#define hicn_uword_bits (1 << hicn_log2_uword_bits)
+
+/* Word types. */
+#if hicn_uword_bits == 64
+/* 64 bit word machines. */
+typedef u64 hicn_uword;
+#else
+/* 32 bit word machines. */
+typedef u32 hicn_uword;
+#endif
+
+typedef hicn_uword hicn_ip_csum_t;
+
+#define hicn_uword_bits (1 << hicn_log2_uword_bits)
+
/* Helper for avoiding warnings about type-punning */
#define UNION_CAST(x, destType) \
(((union { \
@@ -32,12 +67,15 @@ typedef uint64_t u64;
}) x) \
.b)
-// typedef unsigned int hash_t;
-
typedef int (*cmp_t) (const void *, const void *);
/* Enums */
#define IS_VALID_ENUM_TYPE(NAME, x) ((x > NAME##_UNDEFINED) && (x < NAME##_N))
+/* Float */
+
+uint32_t htonf (float f);
+float ntohf (uint32_t i);
+
#endif /* UTIL_TYPES */
diff --git a/lib/includes/hicn/util/vector.h b/lib/includes/hicn/util/vector.h
index 46f195c6d..e693df9e3 100644
--- a/lib/includes/hicn/util/vector.h
+++ b/lib/includes/hicn/util/vector.h
@@ -209,7 +209,7 @@ static inline int
_vector_get (void *vector, off_t pos, size_t elt_size, void *elt)
{
vector_hdr_t *vh = vector_hdr (vector);
- if (pos >= vh->alloc_size)
+ if ((size_t) pos >= vh->alloc_size)
return -1;
memcpy (elt, (uint8_t *) vector + pos * elt_size, elt_size);
@@ -228,7 +228,7 @@ _vector_get (void *vector, off_t pos, size_t elt_size, void *elt)
static inline bool
_vector_contains (void *vector, size_t elt_size, void *elt)
{
- for (int i = 0; i < vector_hdr (vector)->cur_size; i++)
+ for (size_t i = 0; i < vector_hdr (vector)->cur_size; i++)
{
if (memcmp ((uint8_t *) vector + i * elt_size, elt, elt_size) == 0)
return true;
@@ -251,7 +251,7 @@ static inline int
_vector_remove_at (void **vector_ptr, size_t elt_size, off_t pos)
{
vector_hdr_t *vh = vector_hdr (*vector_ptr);
- if (pos >= vh->cur_size)
+ if ((size_t) pos >= vh->cur_size)
return -1;
// Shift backward by one position all the elements after the one specified
@@ -342,7 +342,7 @@ _vector_remove_at (void **vector_ptr, size_t elt_size, off_t pos)
#define vector_at(vector, pos) \
({ \
- assert (pos < vector_hdr (vector)->cur_size); \
+ assert ((size_t) pos < vector_hdr (vector)->cur_size); \
(vector)[(pos)]; \
})
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/includes/hicn/protocol.h b/lib/src/protocol.h
index fb142e4c3..58bbb2ac2 100644
--- a/lib/includes/hicn/protocol.h
+++ b/lib/src/protocol.h
@@ -29,19 +29,6 @@
#include "protocol/udp.h"
#include "protocol/new.h"
-typedef union
-{
- _new_header_t newhdr;
- _ipv4_header_t ipv4;
- _ipv6_header_t ipv6;
- _tcp_header_t tcp;
- _udp_header_t udp;
- _icmp_header_t icmp;
- _icmprd_header_t icmprd;
- _ah_header_t ah;
- void *bytes;
-} hicn_protocol_t;
-
#endif /* HICN_PROTOCOL_H */
/*
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;
+}