aboutsummaryrefslogtreecommitdiffstats
path: root/lib/includes
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-10-07 09:52:33 +0200
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-10-07 15:55:42 +0200
commit6b84ec54083da9911f5ad4816d0eb4f4745afad4 (patch)
treee4296ebb218fff02dc0bbea73ce1c8d12aba7bcc /lib/includes
parent85a791ac2cdd35d79c00141e748b4c68fbdafb0d (diff)
[HICN-298] Release new hICN app for Android
Change-Id: I43adc62fadf00690b687078d739788dffdc5e566 Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Diffstat (limited to 'lib/includes')
-rw-r--r--lib/includes/CMakeLists.txt55
-rw-r--r--lib/includes/hicn/base.h161
-rw-r--r--lib/includes/hicn/common.h316
-rw-r--r--lib/includes/hicn/compat.h461
-rw-r--r--lib/includes/hicn/error.h58
-rw-r--r--lib/includes/hicn/header.h129
-rw-r--r--lib/includes/hicn/hicn.h79
-rw-r--r--lib/includes/hicn/mapme.h162
-rw-r--r--lib/includes/hicn/name.h295
-rw-r--r--lib/includes/hicn/ops.h641
-rw-r--r--lib/includes/hicn/policy.h242
-rw-r--r--lib/includes/hicn/protocol.h51
-rw-r--r--lib/includes/hicn/protocol/ah.h80
-rw-r--r--lib/includes/hicn/protocol/icmp.h84
-rw-r--r--lib/includes/hicn/protocol/icmprd.h72
-rw-r--r--lib/includes/hicn/protocol/ipv4.h105
-rw-r--r--lib/includes/hicn/protocol/ipv6.h80
-rw-r--r--lib/includes/hicn/protocol/tcp.h173
-rw-r--r--lib/includes/hicn/protocol/udp.h44
-rw-r--r--lib/includes/hicn/util/ip_address.h159
-rw-r--r--lib/includes/hicn/util/token.h40
-rw-r--r--lib/includes/hicn/util/types.h36
22 files changed, 3523 insertions, 0 deletions
diff --git a/lib/includes/CMakeLists.txt b/lib/includes/CMakeLists.txt
new file mode 100644
index 000000000..d1eaa0b57
--- /dev/null
+++ b/lib/includes/CMakeLists.txt
@@ -0,0 +1,55 @@
+# Copyright (c) 2017-2019 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.
+
+# XXX
+
+set(HICN_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR} ""
+ CACHE INTERNAL
+ "" FORCE
+)
+
+
+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/header.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/mapme.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/name.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/policy.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ops.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
+ PARENT_SCOPE
+)
+
+set(LIBHICN_HEADER_FILES_UTIL
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/ip_address.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/token.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/types.h
+ PARENT_SCOPE
+)
+
diff --git a/lib/includes/hicn/base.h b/lib/includes/hicn/base.h
new file mode 100644
index 000000000..d8a79a9c2
--- /dev/null
+++ b/lib/includes/hicn/base.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017-2019 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 Base hICN definitions.
+ */
+
+#ifndef HICN_BASE_H
+#define HICN_BASE_H
+
+#include "common.h"
+
+/* Default header fields */
+#define HICN_DEFAULT_TTL 254
+
+typedef u32 hicn_faceid_t;
+typedef u8 hicn_pathlabel_t;
+typedef u32 hicn_lifetime_t;
+
+#define HICN_MAX_LIFETIME_SCALED 0xFFFF
+#define HICN_MAX_LIFETIME_MULTIPLIER 0x0F /* 4 bits */
+#define HICN_MAX_LIFETIME HICN_MAX_LIFETIME_SCALED << HICN_MAX_LIFETIME_MULTIPLIER
+
+/**
+ * @brief hICN packet format type
+ *
+ * The hICN type represents the sequence of protocols that we can find in packet
+ * headers. They are represented as a quartet of u8 values, correponding to
+ * IANA protocol assignment, and read from right to left. This is done to
+ * faciliate decapsulation of packet header by simple shift/mask operations.
+ *
+ * For instance, an IPv6/TCP packet will be identified as :
+ * [IPPROTO_NONE, IPPROTO_NONE, IPPROTO_TCP, IPPROTO_IPV6]
+ *
+ * We expect four elements to be sufficient for most uses, the max being
+ * currently used by an hypothetical signed MAP-Me update :
+ * [IPPROTO_ICMPRD, IPPROTO_AH, IPPROTO_ICMP, IPPROTO_IPV6]
+ */
+typedef union
+{
+ /** protocol layers representation */
+ struct
+ {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ u8 l1; /**< First layer */
+ u8 l2; /**< Second layer */
+ u8 l3; /**< Third layer */
+ u8 l4; /**< Fourth layer */
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ u8 l4; /**< Fourth layer */
+ u8 l3; /**< Third layer */
+ u8 l2; /**< Second layer */
+ u8 l1; /**< First layer */
+#elif _WIN32 /* Windows is assumed little-endian */
+ u8 l1;
+ u8 l2;
+ u8 l3;
+ u8 l4;
+#else
+#error "Unsupported endianness"
+#endif
+ };
+ /** u32 representation */
+ u32 as_u32;
+} hicn_type_t;
+
+/* Common protocol layers */
+/* Common protocol layers */
+#ifndef _WIN32
+#define HICN_TYPE(x,y,z,t) (hicn_type_t) {{ .l1 = x, .l2 = y, .l3 = z, .l4 = t }}
+#else
+inline hicn_type_t
+HICN_TYPE(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;
+}
+#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_IPV4_TCP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_TYPE_IPV4_ICMP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, 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_NONE HICN_TYPE(IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
+
+/**
+ * @brief hICN Payload type
+ *
+ * This type distinguishes several types of data packet, which can either carry
+ * content data, or Manifest
+ */
+typedef enum
+{
+ HPT_DATA = 0,
+ HPT_MANIFEST = 1,
+ HPT_UNSPEC = 999
+} hicn_payload_type_t;
+
+/**
+ * @brief Path label computations
+ *
+ * Path label is computed by accumulating the identifiers of successive output
+ * faces as a Data packet is traveling from its producer back to the consumer
+ * originating the Interest.
+ *
+ * NOTE: this computation is not (yet) part of the hICN specification.
+ */
+
+#define HICN_PATH_LABEL_MASK 0xF000 /* 1000 0000 0000 0000 */
+#define HICN_PATH_LABEL_SIZE 8
+
+/**
+ * @brief Path label update
+ * @param [in] current_label Current pathlabel
+ * @param [in] face_id The face identifier to combine into the path label
+ * @param [out] new_label Computed pathlabel
+ *
+ * This function updates the current_label based on the new face_id, and returns
+ */
+always_inline void
+update_pathlabel (hicn_pathlabel_t current_label, hicn_faceid_t face_id,
+ hicn_pathlabel_t * new_label)
+{
+ hicn_pathlabel_t pl_face_id =
+ (hicn_pathlabel_t) ((face_id & HICN_PATH_LABEL_MASK) >>
+ (16 - HICN_PATH_LABEL_SIZE));
+ *new_label =
+ ((current_label << 1) | (current_label >> (HICN_PATH_LABEL_SIZE - 1))) ^
+ pl_face_id;
+}
+
+#endif /* HICN_BASE_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h
new file mode 100644
index 000000000..33323da1b
--- /dev/null
+++ b/lib/includes/hicn/common.h
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2017-2019 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 common.c
+ * @brief Common interfaces abstracting low-level platform.
+ * details.
+ *
+ * The role of this header file is to provide an uniform interface to the
+ * different platform on top of which we build the hICN interface:
+ * - syntax helpers
+ * - IP address management
+ * - protocol definition
+ * - ...
+ *
+ * The rationale is to leverage as much as possible platform-specific code,
+ * however some level of harmonization is needed to build code on top. Whenever
+ * possible, we align to VPP structure and naming.
+ */
+
+#ifndef HICN_COMMON_H
+#define HICN_COMMON_H
+
+#include <stdint.h>
+#include <assert.h>
+
+/* Concise type definitions */
+
+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 always_inline static inline
+#define static_always_inline static inline
+#define STRUCT_SIZE_OF(type, member) sizeof(((type *)0)->member)
+#define ASSERT
+
+#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;
+
+#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 macro, or
+ * duplicate some code, with the intent of preserving those safeguards for
+ * non-Windows platforms.
+ */
+#ifndef _WIN32
+#define ATTR_INIT(key, value) .key = value
+#else
+#define ATTR_INIT(key, value) value
+#endif
+
+#ifdef _WIN32
+ /* Endianness detection for Windows platforms */
+#define __ORDER_LITTLE_ENDIAN__ 0x41424344UL
+#define __ORDER_BIG_ENDIAN__ 0x44434241UL
+#define __BYTE_ORDER__ ('ABCD')
+
+ /* Windows compatibility headers */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2ipdef.h>
+#include <Ws2tcpip.h>
+#include <In6addr.h>
+
+#define strdup _strdup
+#define __attribute__(A)
+
+#ifndef IOVEC
+#define IOVEC
+#define UIO_MAXIOV 16
+#define IOV_MAX UIO_MAXIOV
+struct iovec
+{
+ void *iov_base;
+ size_t iov_len;
+};
+#endif
+#endif
+
+/*
+ * Portable attribute packed.
+ */
+#ifndef _WIN32
+#define PACKED( __Declaration__ ) __Declaration__ __attribute__((__packed__))
+#else
+#define PACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
+#endif
+
+
+/*
+ * IP address types
+ */
+
+#ifdef HICN_VPP_PLUGIN
+
+#include <vnet/ip/ip4_packet.h> // ip4_address_t
+#include <vnet/ip/ip6_packet.h> // ip6_address_t
+
+#else
+
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#endif
+
+typedef union
+{
+ u32 as_u32;
+ struct in_addr as_inaddr;
+} ip4_address_t;
+
+typedef union
+{
+ u64 as_u64[2];
+ u32 as_u32[4];
+ u8 as_u8[16];
+ struct in6_addr as_in6addr;
+} ip6_address_t;
+
+typedef union
+{
+ struct
+ {
+ u32 pad[3];
+ ip4_address_t ip4;
+ };
+ ip6_address_t ip6;
+} ip46_address_t;
+
+#define ip46_address_is_ip4(ip46) (((ip46)->pad[0] | (ip46)->pad[1] | (ip46)->pad[2]) == 0)
+
+#endif /* ! HICN_VPP_PLUGIN */
+
+/**
+ * @brief Returns the family of an IP address
+ * @param [in] ip_address - IP address in presentation format
+ * @return AF_INET or AF_INET6 if successful, -1 otherwise
+ */
+int get_addr_family (const char *ip_address);
+
+/*
+ * Checksum computation
+ *
+ * NOTE: VPP provides efficient (incremental) checksum computations
+ * that we reuse, and provide alternative implementation otherwise.
+ */
+
+#ifndef HICN_VPP_PLUGIN
+
+/*
+ * Checksum update (incremental and non-incremental)
+ *
+ * Those functions are already defined in VPP in vnet/ip/ip_packet.h, and we
+ * borrow this code here.
+ */
+
+static_always_inline u16
+ip_csum_fold (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 & 0xffff) + (c >> 16);
+#endif
+
+ c = (c & 0xffff) + (c >> 16);
+ c = (c & 0xffff) + (c >> 16);
+
+ return (u16)c;
+}
+
+static_always_inline ip_csum_t
+ip_csum_with_carry (ip_csum_t sum, ip_csum_t x)
+{
+ ip_csum_t t = sum + x;
+ return t + (t < x);
+}
+
+/* Update checksum changing field at even byte offset from x -> 0. */
+static_always_inline ip_csum_t
+ip_csum_add_even (ip_csum_t c, ip_csum_t x)
+{
+ ip_csum_t d;
+
+ d = c - x;
+
+ /* Fold in carry from high bit. */
+ d -= d > c;
+
+ return d;
+}
+
+/* Update checksum changing field at even byte offset from 0 -> x. */
+static_always_inline ip_csum_t
+ip_csum_sub_even (ip_csum_t c, ip_csum_t x)
+{
+ return ip_csum_with_carry (c, x);
+}
+
+u32 cumulative_hash32 (const void *data, size_t len, u32 lastValue);
+u32 hash32 (const void *data, size_t len);
+u64 cumulative_hash64 (const void *data, size_t len, u64 lastValue);
+u64 hash64 (const void *data, size_t len);
+void hicn_packet_dump (uint8_t * buffer, size_t len);
+
+#endif /* ! HICN_VPP_PLUGIN */
+
+/**
+ * @brief Computes buffer checksum
+ * @param [in] addr - Pointer to buffer start
+ * @param [in] size - Size of buffer
+ * @param [in] init - Checksum initial value
+ * @return Checksum of specified buffer
+ */
+always_inline u16
+csum (const void *addr, size_t size, u16 init)
+{
+ u32 sum = init;
+ const u16 *bytes = (u16 *) addr;
+
+ while (size > 1)
+ {
+ sum += *bytes++;
+ size -= sizeof (u16);
+ }
+ if (size)
+ {
+ sum += *(const u8 *) bytes;
+ }
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+
+ return (u16) ~ sum;
+}
+
+/*
+ * Useful aliases
+ */
+
+/* Symmetry with IPPROTO_ICMPV6 */
+#define IPPROTO_ICMPV4 IPPROTO_ICMP
+
+/*
+ * 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)->v4.ip.version
+
+/*
+ * ntohll / htonll allows byte swapping for 64 bits integers
+ */
+#ifndef htonll
+#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
+#endif
+
+#ifndef ntohll
+#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
+#endif
+
+#endif /* HICN_COMMON_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/compat.h b/lib/includes/hicn/compat.h
new file mode 100644
index 000000000..b31d01a0d
--- /dev/null
+++ b/lib/includes/hicn/compat.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2017-2019 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_ICMP 1 << 3
+#define HFO_AH 1 << 4
+
+#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_icmp(format) ((format & HFO_ICMP) >> 3)
+#define _is_ah(format) ((format & HFO_AH) >> 4)
+
+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_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
+} hicn_format_t;
+
+/**
+ * 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
+
+/**
+ * @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 (hicn_format_t format,
+ hicn_header_t * packet);
+
+// 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_prefix_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_prefix_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);
+
+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 (const hicn_header_t * packet, u32 * lifetime);
+int hicn_packet_set_lifetime (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 (const hicn_header_t * packet,
+ hicn_payload_type_t * payload_type);
+int hicn_packet_set_payload_type (hicn_header_t * packet,
+ const hicn_payload_type_t payload_type);
+
+int hicn_packet_set_syn (hicn_header_t * packet);
+int hicn_packet_reset_syn (hicn_header_t * packet);
+int hicn_packet_test_syn (const hicn_header_t * packet, bool * flag);
+int hicn_packet_set_ack (hicn_header_t * packet);
+int hicn_packet_reset_ack (hicn_header_t * packet);
+int hicn_packet_test_ack (const hicn_header_t * packet, bool * flag);
+int hicn_packet_set_rst (hicn_header_t * packet);
+int hicn_packet_reset_rst (hicn_header_t * packet);
+int hicn_packet_test_rst (const hicn_header_t * packet, bool * flag);
+int hicn_packet_set_fin (hicn_header_t * packet);
+int hicn_packet_reset_fin (hicn_header_t * packet);
+int hicn_packet_test_fin (const hicn_header_t * packet, bool * flag);
+int hicn_packet_set_ece (hicn_header_t * packet);
+int hicn_packet_reset_ece (hicn_header_t * packet);
+int hicn_packet_test_ece (const hicn_header_t * packet, bool * flag);
+
+int hicn_packet_set_src_port (hicn_header_t * packet, u16 src_port);
+int hicn_packet_get_src_port (const hicn_header_t * packet, u16 * src_port);
+int hicn_packet_set_dst_port (hicn_header_t * packet, u16 dst_port);
+int hicn_packet_get_dst_port (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_prefix_t * prefix);
+int hicn_interest_set_locator (hicn_format_t format, hicn_header_t * interest,
+ const ip_prefix_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_prefix_t * prefix);
+int hicn_data_set_locator (hicn_format_t format, hicn_header_t * data,
+ const ip_prefix_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);
+
+#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
new file mode 100644
index 000000000..3e027c4e5
--- /dev/null
+++ b/lib/includes/hicn/error.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017-2019 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 error.h
+ * @brief Error management functions.
+ */
+#ifndef HICN_ERROR_H
+#define HICN_ERROR_H
+
+/******************************************************************************
+ * Error definitions
+ ******************************************************************************/
+
+#define foreach_libhicn_error \
+_(NONE, 0, "OK") \
+_(UNSPECIFIED, 128, "Unspecified Error") \
+_(NOT_IMPLEMENTED, 180, "Function not yet implemented") \
+_(NOT_HICN, 202, "Non hICN packet") \
+_(UNKNOWN_ADDRESS, 210, "Unknown address") \
+_(INVALID_PARAMETER, 220, "Invalid parameter") \
+_(INVALID_IP_ADDRESS, 221, "Invalid IP address") \
+_(CORRUPTED_PACKET, 222, "Corrupted packet ") \
+_(UNEXPECTED, 298, "Unexpected error")
+
+typedef enum
+{
+#define _(a,b,c) HICN_LIB_ERROR_##a = (-b),
+ foreach_libhicn_error
+#undef _
+ HICN_LIB_N_ERROR,
+} hicn_lib_error_t;
+
+extern const char *HICN_LIB_ERROR_STRING[];
+
+#define hicn_strerror(errno) (char *)(HICN_LIB_ERROR_STRING[-errno])
+
+#endif /* HICN_ERROR_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/header.h b/lib/includes/hicn/header.h
new file mode 100644
index 000000000..b21fe5c84
--- /dev/null
+++ b/lib/includes/hicn/header.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017-2019 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;
+ _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
+ {
+ _icmp_header_t icmp;
+ _ah_header_t icmp_ah;
+ };
+ };
+} hicn_v6ah_hdr_t;
+
+typedef struct
+{
+ _ipv4_header_t ip;
+ union
+ {
+ _tcp_header_t tcp;
+ _icmp_header_t icmp;
+ _icmp_wldr_header_t wldr;
+ };
+} hicn_v4_hdr_t;
+
+typedef struct
+{
+ _ipv4_header_t ip;
+ union
+ {
+ struct
+ {
+ _tcp_header_t tcp;
+ _ah_header_t 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)
+
+
+
+
+#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
new file mode 100644
index 000000000..749fd4247
--- /dev/null
+++ b/lib/includes/hicn/hicn.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017-2019 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 hicn.h
+ * @brief hICN master include file.
+ *
+ * Reference: https://tools.ietf.org/html/draft-muscariello-intarea-hicn
+ *
+ * This file is the entry point for projects to libhicn, which provides a
+ * reference implementation for hICN specifications [1], including:
+ * - naming
+ * - packet headers
+ * - protocol mappings (IPv4, IPv6, TCP, ICMP, AH)
+ * - protocol independent packet operations
+ * - helpers for additional features such as Wireless Loss Detection and
+ * Recovery (WLDR) [2], Anchorless Mobility Management (hICN-AMM) [3],
+ * including MAP-Me producer mobility mechanisms [4].
+ *
+ * [1] Hybrid Information-Centric Networking
+ * L. Muscariello, G. Carofiglio, J. Augé, M. Papalini
+ * IETF draft (intarea) @ https://tools.ietf.org/html/draft-muscariello-intarea-hicn
+ *
+ * [2] Leveraging ICN in-network control for loss detection and recovery in wireless mobile networks
+ * G. Carofiglio, L. Muscariello, M. Papalini, N. Rozhnova, X. Zeng
+ * In proc. ICN'2016, Kyoto, JP
+ *
+ * [3] Anchorless mobility through hICN
+ * J. Augé, G. Carofiglio, L. Muscariello, M. Papalini
+ * IETF draft (DMM) @ https://tools.ietf.org/html/draft-auge-dmm-hicn-mobility
+ *
+ *
+ * [4] MAP-Me : Managing Anchorless Mobility in Content Centric Networking
+ * J. Augé, G. Carofiglio, L. Muscariello, M. Papalini
+ * IRTF draft (ICNRG) @ https://tools.ietf.org/html/draft-irtf-icnrg-mapme
+ */
+
+#ifndef HICN__H
+#define HICN__H
+
+#ifdef HICN_VPP_PLUGIN
+
+#include <hicn/header.h>
+#include <hicn/name.h>
+#include <hicn/ops.h>
+#include <hicn/mapme.h>
+
+#else
+
+#include <hicn/error.h>
+#include <hicn/header.h>
+#include <hicn/name.h>
+#include <hicn/ops.h>
+#include <hicn/mapme.h>
+#include <hicn/compat.h>
+
+#endif
+
+#endif /* HICN__H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/mapme.h b/lib/includes/hicn/mapme.h
new file mode 100644
index 000000000..8fae44530
--- /dev/null
+++ b/lib/includes/hicn/mapme.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017-2019 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 mapme.h
+ * @brief MAP-Me anchorless producer mobility management.
+ */
+#ifndef HICN_MAPME_H
+#define HICN_MAPME_H
+
+#include <stdint.h> // u32
+#include <stdbool.h>
+
+#include "common.h"
+#include "protocol.h"
+#include "ops.h"
+
+/**
+ * @brief MAP-Me configuration options
+ */
+typedef struct
+{
+ /** MAP-Me enabled flag (default: false) */
+ bool enabled;
+ /** timescale (T_U parameter) in ms (default: 0 for no notifications) */
+ u32 timescale;
+ /** retransmission timer in ms (default: 50) */
+ u32 retx;
+ /**
+ * Discovery enabled flag (default: true, should be true if mandatory is
+ * notifications are enabled)
+ */
+ bool discovery;
+} hicn_mapme_conf_t;
+
+/** @brief Default MAP-Me configuration */
+static const hicn_mapme_conf_t hicn_mapme_conf = {
+ ATTR_INIT (enabled, false),
+ ATTR_INIT (timescale, 0),
+ ATTR_INIT (retx, 50),
+ ATTR_INIT (discovery, true),
+};
+
+/** @brief MAP-Me update sequence number */
+typedef u32 seq_t;
+
+/** @brief MAP-Me packet types */
+typedef enum
+{
+ UNKNOWN,
+ UPDATE,
+ UPDATE_ACK,
+ NOTIFICATION,
+ NOTIFICATION_ACK,
+} hicn_mapme_type_t;
+
+/** @brief MAP-Me parameters (excluding those contained in * hicn_prefix_t) */
+typedef struct
+{
+ int protocol;
+ hicn_mapme_type_t type;
+ seq_t seq;
+} mapme_params_t;
+
+
+/* MAP-Me API */
+size_t hicn_mapme_create_packet (u8 * buf, const hicn_prefix_t * prefix,
+ const mapme_params_t * params);
+size_t hicn_mapme_create_ack (u8 * buf, const mapme_params_t * params);
+int hicn_mapme_parse_packet (const u8 * packet, hicn_prefix_t * prefix,
+ mapme_params_t * params);
+
+/* Implementation & parsing : ICMP Redirect */
+
+#define HICN_MAPME_ACK_FLAG (0x20 | 0x60)
+
+#define HICN_MAPME_ICMP_TYPE_IPV4 5
+#define HICN_MAPME_ICMP_TYPE_IPV6 137
+#define HICN_MAPME_ICMP_TYPE_ACK_IPV4 (HICN_MAPME_ICMP_TYPE_IPV4 | HICN_MAPME_ACK_FLAG)
+#define HICN_MAPME_ICMP_TYPE_ACK_IPV6 (HICN_MAPME_ICMP_TYPE_IPV6 | HICN_MAPME_ACK_FLAG)
+#define HICN_MAPME_ICMP_CODE 0 /* Redirect Datagrams for the Network (or subnet) */
+
+#define HICN_MAPME_TYPE_IS_IU(type) ((type == HICN_MAPME_ICMP_TYPE_IPV4) || (type == HICN_MAPME_ICMP_TYPE_IPV6))
+#define HICN_MAPME_TYPE_IS_IU_ACK(type) ((type == HICN_MAPME_ICMP_TYPE_ACK_IPV4) || (type == HICN_MAPME_ICMP_TYPE_ACK_IPV6))
+
+#define HICN_MAPME_IS_IU(type, code) (HICN_MAPME_TYPE_IS_IU(type) && (code == HICN_MAPME_ICMP_CODE))
+#define HICN_MAPME_IS_ACK(type, code) (HICN_MAPME_TYPE_IS_IU_ACK(type) && (code == HICN_MAPME_ICMP_CODE))
+
+#define HICN_IS_MAPME(type, code) (HICN_MAPME_IS_IU(type, code) || HICN_MAPME_IS_ACK(type, code))
+
+/* Fast check for ACK flag */
+#define HICN_MAPME_IS_ACK_FAST(icmp_type) (icmp_type & HICN_MAPME_ACK_FLAG)
+
+/* 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;
+
+/*
+ * The length of the MAPME4 header struct must be bytes.
+ */
+#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 */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/name.h b/lib/includes/hicn/name.h
new file mode 100644
index 000000000..0a100dbce
--- /dev/null
+++ b/lib/includes/hicn/name.h
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2017-2019 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 name.h
+ * @brief hICN name helpers.
+ *
+ * The purpose of the file is to offer an efficient, platform- and protocol-
+ * independent way to manipulate hICN names.
+ */
+
+#ifndef HICN_NAME_H
+#define HICN_NAME_H
+
+#include <stdbool.h>
+#ifndef _WIN32
+#include <netinet/in.h> // struct sockadd
+#endif
+#include <hicn/util/ip_address.h>
+#include "common.h"
+
+/******************************************************************************
+ * hICN names
+ ******************************************************************************/
+
+#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
+#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 */
+
+/* Prefix */
+
+typedef u32 hicn_name_suffix_t;
+
+typedef struct
+{
+ ip46_address_t name;
+ u8 len;
+} hicn_prefix_t;
+
+/*
+ * Name
+ *
+ * A name is a prefix + a segment name (suffix)
+ */
+
+typedef union
+{
+ struct
+ {
+ union
+ {
+ u32 prefix;
+ u8 prefix_as_u8[4];
+ ip4_address_t prefix_as_ip4;
+ };
+ hicn_name_suffix_t suffix;
+ };
+ u8 buffer[HICN_V4_NAME_LEN];
+} hicn_v4_name_t;
+
+typedef union
+{
+ struct
+ {
+ union
+ {
+ u64 prefix[2];
+ u8 prefix_as_u8[16];
+ ip6_address_t prefix_as_ip6;
+ };
+ hicn_name_suffix_t suffix;
+ };
+ u8 buffer[HICN_V6_NAME_LEN];
+} hicn_v6_name_t;
+
+typedef struct
+{
+ u8 buffer[0];
+} hicn_v46_name_t;
+
+#ifndef HICN_VPP_PLUGIN
+#define HICN_NAME_COMPONENT_SIZE 2
+
+typedef struct
+{
+ struct iovec buffers[HICN_NAME_COMPONENT_SIZE];
+} hicn_iov_name_t;
+
+#define UNSPEC 1 << 0
+#define HNT_CONTIGUOUS 1 << 1
+#define HNT_IOV 1 << 2
+#define HNT_INET 1 << 3
+#define HNT_INET6 1 << 4
+
+typedef enum
+{
+ HNT_UNSPEC = UNSPEC,
+ HNT_CONTIGUOUS_V4 = HNT_CONTIGUOUS | HNT_INET,
+ HNT_CONTIGUOUS_V6 = HNT_CONTIGUOUS | HNT_INET6,
+ HNT_IOV_V4 = HNT_IOV | HNT_INET,
+ HNT_IOV_V6 = HNT_IOV | HNT_INET6,
+} hicn_name_type_t;
+#endif /* HICN_VPP_PLUGIN */
+
+typedef struct
+{
+#ifndef HICN_VPP_PLUGIN
+ hicn_name_type_t type;
+ u8 len;
+#endif /* HICN_VPP_PLUGIN */
+ union
+ {
+ hicn_v4_name_t ip4;
+ hicn_v6_name_t ip6;
+ ip46_address_t ip46;
+#ifndef HICN_VPP_PLUGIN
+ hicn_iov_name_t iov;
+ u8 buffer[0];
+#endif /* HICN_VPP_PLUGIN */
+ };
+} hicn_name_t;
+
+#ifndef HICN_VPP_PLUGIN
+#define _is_unspec(name) ((name->type & UNSPEC))
+#define _is_contiguous(name) ((name->type & HNT_CONTIGUOUS) >> 1)
+#define _is_iov(name) ((name->type & HNT_IOV) >> 2)
+#define _is_inet4(name) ((name->type & HNT_INET) >> 3)
+#define _is_inet6(name) ((name->type & HNT_INET6) >> 4)
+#endif /* HICN_VPP_PLUGIN */
+
+/**
+ * @brief Create an hICN name from IP address in presentation format
+ * @param [in] ip_address - IP address
+ * @param [in] id - Segment identifier
+ * @param [out] Resulting hICN name
+ * @return hICN error code
+ */
+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 [out] Resulting - hICN name
+ * @return hICN error code
+ */
+int hicn_name_create_from_ip_prefix (const ip_prefix_t * prefix, u32 id,
+ hicn_name_t * name);
+
+/**
+ * @brief Returns the length of an hICN name
+ * @param [in] name - hICN name
+ * @return Name length
+ */
+u8 hicn_name_get_length (const hicn_name_t * name);
+
+/**
+ * @brief Compare two hICN names
+ * @param [in] name_1 - First name to compare
+ * @param [in] name_2 - Second name to compare
+ * @param [in] consider_segment - Flag indicating whether the segment part has to be
+ * considered
+ * @return An integer less than, equal to, or greater than zero if name_1 is
+ * found, respectively, to be lest than, to match, or be greater than name_2
+ * based on numeric order.
+ */
+int hicn_name_compare (const hicn_name_t * name_1, const hicn_name_t * name_2,
+ bool consider_segment);
+
+/**
+ * @brief Provides a 32-bit hash of an hICN name
+ * @param [in] name - Name to hash
+ * @param [out] hash - Resulting hash
+ * @return hICN error code
+ */
+int hicn_name_hash (const hicn_name_t * name, u32 * hash);
+
+/**
+ * @brief Test whether an hICN name is empty
+ * @param [in] name - Name to test
+ * @return 0 if the name is empty, any other value otherwise (implementation
+ * returns 1)
+ */
+int hicn_name_empty (hicn_name_t * name);
+
+/**
+ * @brief Copy an hICN name
+ * @param [out] dst - Destination name
+ * @param [in] src - Source name to copy
+ * @return hICN error code
+ */
+int hicn_name_copy (hicn_name_t * dst, const hicn_name_t * src);
+
+/**
+ * @brief Copy an hICN name to a buffer
+ * @param [out] dst - Destination buffer
+ * @param [in] src - Source name to copy
+ * @param [in] copy_suffix - Flag indicating whether the suffix has to be
+ * considered
+ */
+int hicn_name_copy_to_destination (u8 * dst, const hicn_name_t * src,
+ bool copy_suffix);
+
+/**
+ * @brief Sets the segment part of an hICN name
+ * @param [in,out] name - hICN name to modify
+ * @param [in] seq_number - Segment identifier
+ * @return hICN error code
+ */
+int hicn_name_set_seq_number (hicn_name_t * name, u32 seq_number);
+
+/**
+ * @brief Retrieves the segment part of an hICN name
+ * @param [in,out] name - hICN name
+ * @param [in] seq_number - Segment identifier
+ * @return hICN error code
+ */
+int hicn_name_get_seq_number (const hicn_name_t * name, u32 * seq_number);
+
+/**
+ * @brief Convert an hICN name to a socket address
+ * @param [in] name - Name to convert
+ * @param [out] ip_address - Resulting socket address
+ * @return hICN error code
+ */
+int hicn_name_to_sockaddr_address (const hicn_name_t * name,
+ struct sockaddr *ip_address);
+
+/**
+ * @brief Convert an hICN name to an IP address
+ * @param [in] name - Name to convert
+ * @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);
+
+/**
+ * @brief Convert an hICN name to presentation format
+ * @param [in] src - Name to convert
+ * @param [out] dst - Buffer to receive the name in presentation format
+ * @param [in] len - Number of bytes available in the buffer
+ * @return hICN error code
+ */
+int hicn_name_ntop (const hicn_name_t * src, char *dst, size_t len);
+
+/**
+ * @brief Convert an hICN name from presentation format
+ * @param [in] src - Name in presentation format to parse
+ * @param [out] dst - Resulting name
+ * @return hICN error code
+ */
+int hicn_name_pton (const char *src, hicn_name_t * dst);
+
+/**
+ * @brief Returns the IP address family of an hICN name
+ * @param [in] name - Name to lookup
+ * @param [out] family - Resulting IP address family (AF_INET or AF_INET6)
+ * @return hICN error code
+ */
+int hicn_name_get_family (const hicn_name_t * name, int *family);
+
+/**
+ * @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,
+ hicn_prefix_t * prefix);
+
+#endif /* HICN_NAME_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/ops.h b/lib/includes/hicn/ops.h
new file mode 100644
index 000000000..47795efd5
--- /dev/null
+++ b/lib/includes/hicn/ops.h
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2017-2019 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 "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,
+ ip46_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 ip46_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 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,
+ ip46_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 ip46_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 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 (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 (*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 ip46_address_t * addr_new,
+ ip46_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
+ * @return hICN error code
+ */
+ int (*rewrite_data) (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new,
+ ip46_address_t * addr_old,
+ const hicn_faceid_t face_id);
+
+ /**
+ * @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 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);
+} 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(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(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_signature_size, protocol ## _get_signature_size), \
+ ATTR_INIT(set_signature_size, protocol ## _set_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), \
+ }
+
+/**
+ * @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...)
+ */
+always_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
+}
+
+always_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, ip46_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 ip46_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_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, ip46_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 ip46_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_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 ip46_address_t * addr_new, ip46_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 ip46_address_t * addr_new, ip46_address_t * addr_old, const hicn_faceid_t face_id) { 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_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_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 ; }
+
+#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/policy.h b/lib/includes/hicn/policy.h
new file mode 100644
index 000000000..12f8c1e12
--- /dev/null
+++ b/lib/includes/hicn/policy.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2017-2019 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 policy.h
+ * \brief Policy description
+ */
+#ifndef HICN_POLICY_H
+#define HICN_POLICY_H
+
+#include <netinet/in.h> // INET*_ADDRSTRLEN
+#include <string.h> // strcasecmp
+#include <hicn/util/token.h>
+
+/* POLICY TAG */
+
+#define foreach_policy_tag \
+ /* Interface type */ \
+ _(WIRED, 'E') \
+ _(WIFI, 'W') \
+ _(CELLULAR, 'C') \
+ /* QoS */ \
+ _(BEST_EFFORT, 'b') \
+ _(REALTIME, 'r') \
+ _(MULTIPATH, 'M') \
+ /* Security */ \
+ _(TRUSTED, 'T')
+
+typedef enum {
+#define _(x, y) POLICY_TAG_ ## x,
+foreach_policy_tag
+#undef _
+ POLICY_TAG_N
+} policy_tag_t;
+
+#define MAXSZ_POLICY_TAG_ 11
+#define MAXSZ_POLICY_TAG MAXSZ_POLICY_TAG_ + 1
+
+extern const char * policy_tag_str[];
+extern const char policy_tag_short_str[];
+
+static inline
+policy_tag_t
+policy_tag_from_str(const char * str)
+{
+#define _(x, y) if (strcasecmp(str, policy_tag_str[POLICY_TAG_ ## x] ) == 0) { return POLICY_TAG_ ## x; } else
+foreach_policy_tag
+#undef _
+ return POLICY_TAG_N;
+}
+
+/* POLICY_TAGS */
+
+typedef int policy_tags_t;
+
+static inline
+void policy_tags_add(policy_tags_t * tags, policy_tag_t tag)
+{
+ *tags |= (1 << tag);
+}
+
+static inline
+void policy_tags_remove(policy_tags_t * tags, policy_tag_t tag)
+{
+ *tags &= ~(1 << tag);
+}
+
+static inline
+int policy_tags_has(policy_tags_t tags, policy_tag_t tag)
+{
+ return tags & (1 << tag);
+}
+
+static inline
+void policy_tags_union(policy_tags_t * tags, policy_tags_t * tags_to_union)
+{
+#define _(x, y) *tags |= policy_tags_has(*tags_to_union, POLICY_TAG_ ## x) ? (1 << POLICY_TAG_ ## x) : 0;
+foreach_policy_tag
+#undef _
+}
+
+#define POLICY_TAGS_EMPTY 0
+
+static inline
+int
+policy_tags_snprintf(char * s, size_t size, policy_tags_t tags)
+{
+#define _(x, y) s[POLICY_TAG_ ## x] = policy_tags_has(tags, POLICY_TAG_ ## x) ? y : '.';
+foreach_policy_tag
+#undef _
+ s[POLICY_TAG_N] = '\0';
+ return POLICY_TAG_N + 1;
+}
+
+#define MAXSZ_POLICY_TAGS_ POLICY_TAG_N
+#define MAXSZ_POLICY_TAGS MAXSZ_POLICY_TAGS_ + 1
+
+/* POLICY STATE */
+
+/* TODO vs. weight */
+
+#define foreach_policy_state \
+ _(NEUTRAL) \
+ _(REQUIRE) \
+ _(PREFER) \
+ _(AVOID) \
+ _(PROHIBIT) \
+ _(N)
+
+typedef enum {
+#define _(x) POLICY_STATE_ ## x,
+foreach_policy_state
+#undef _
+} policy_state_t;
+
+#define MAXSZ_POLICY_STATE_ 8
+#define MAXSZ_POLICY_STATE MAXSZ_POLICY_STATE_ + 1
+
+extern const char * policy_state_str[];
+
+
+/* POLICY TAG STATE */
+
+typedef struct {
+ policy_state_t state;
+ uint8_t disabled;
+} policy_tag_state_t;
+
+#define MAXSZ_POLICY_TAG_STATE_ 8
+#define MAXSZ_POLICY_TAG_STATE MAXSZ_POLICY_TAG_STATE_ + 1
+
+int policy_tag_state_snprintf(char * s, size_t size, const policy_tag_state_t * tag_state);
+
+
+/* INTERFACE STATS */
+
+typedef struct {
+ float throughput;
+ float latency;
+ float loss_rate;
+} interface_stats_t;
+
+#define INTERFACE_STATS_NONE { \
+ .throughput = 0, \
+ .latency = 0, \
+ .loss_rate = 0, \
+}
+
+
+/* POLICY STATS */
+
+typedef struct {
+ interface_stats_t wired;
+ interface_stats_t wifi;
+ interface_stats_t cellular;
+ interface_stats_t all;
+} policy_stats_t;
+
+#define POLICY_STATS_NONE { \
+ .wired = INTERFACE_STATS_NONE, \
+ .wifi = INTERFACE_STATS_NONE, \
+ .cellular = INTERFACE_STATS_NONE, \
+ .all = INTERFACE_STATS_NONE, \
+}
+
+typedef struct {
+ uint32_t num_packets;
+ uint32_t num_bytes;
+ uint32_t num_losses;
+ uint32_t latency_idle;
+} interface_counters_t;
+
+#define INTERFACE_COUNTERS_NONE { \
+ .num_packets = 0, \
+ .num_bytes = 0, \
+ .num_losses = 0, \
+ .latency_idle = 0, \
+}
+
+typedef struct {
+ interface_counters_t wired;
+ interface_counters_t wifi;
+ interface_counters_t cellular;
+ interface_counters_t all;
+ uint64_t last_update;
+} policy_counters_t;
+
+#define POLICY_COUNTERS_NONE (policy_counters_t) { \
+ .wired = INTERFACE_COUNTERS_NONE, \
+ .wifi = INTERFACE_COUNTERS_NONE, \
+ .cellular = INTERFACE_COUNTERS_NONE, \
+ .all = INTERFACE_COUNTERS_NONE, \
+ .last_update = 0, \
+}
+
+/* POLICY */
+
+#define APP_NAME_LEN 128
+
+typedef struct {
+ char app_name[APP_NAME_LEN];
+ policy_tag_state_t tags[POLICY_TAG_N];
+ policy_stats_t stats;
+} policy_t;
+
+static const policy_t POLICY_NONE = {
+ .app_name = { 0 },
+ .tags = {
+#define _(x, y) [POLICY_TAG_ ## x] = { POLICY_STATE_NEUTRAL, 0 },
+foreach_policy_tag
+#undef _
+ },
+ .stats = POLICY_STATS_NONE,
+};
+
+
+/* POLICY DESCRIPTION */
+
+#define PFX_STRLEN 4 /* eg. /128 */
+
+typedef struct {
+ int family;
+ union {
+ char ipv4_prefix[INET_ADDRSTRLEN + PFX_STRLEN];
+ char ipv6_prefix[INET6_ADDRSTRLEN + PFX_STRLEN];
+ };
+ policy_t policy;
+} policy_description_t;
+
+#endif /* HICN_POLICY_H */
diff --git a/lib/includes/hicn/protocol.h b/lib/includes/hicn/protocol.h
new file mode 100644
index 000000000..a97cc99cf
--- /dev/null
+++ b/lib/includes/hicn/protocol.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file protocol.h
+ * @brief Protocol header definitions
+ */
+#ifndef HICN_PROTOCOL_H
+#define HICN_PROTOCOL_H
+
+#include "protocol/ah.h"
+#include "protocol/ipv4.h"
+#include "protocol/ipv6.h"
+#include "protocol/icmp.h"
+#include "protocol/icmprd.h"
+#include "protocol/tcp.h"
+#include "protocol/udp.h"
+
+typedef union
+{
+ _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 */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/protocol/ah.h b/lib/includes/hicn/protocol/ah.h
new file mode 100644
index 000000000..a59a5051a
--- /dev/null
+++ b/lib/includes/hicn/protocol/ah.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019 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 "../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)
+ u8 payloadlen; // Len of signature/HMAC in 4-bytes words
+ union
+ {
+ u16 reserved;
+
+ struct
+ {
+ u8 validationAlgorithm; // As defined in parc_SignerAlgorithm.h
+ u8 unused; // Unused (to match with reserved in IPSEC AH)
+ };
+ };
+ 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 the 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/includes/hicn/protocol/icmp.h b/lib/includes/hicn/protocol/icmp.h
new file mode 100644
index 000000000..36954bb6d
--- /dev/null
+++ b/lib/includes/hicn/protocol/icmp.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2019 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 "../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/includes/hicn/protocol/icmprd.h b/lib/includes/hicn/protocol/icmprd.h
new file mode 100644
index 000000000..aa1fa01ae
--- /dev/null
+++ b/lib/includes/hicn/protocol/icmprd.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017-2019 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 "../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;
+ ip4_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;
+ ip6_address_t tgt;
+ ip6_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/includes/hicn/protocol/ipv4.h b/lib/includes/hicn/protocol/ipv4.h
new file mode 100644
index 000000000..8a5b6683b
--- /dev/null
+++ b/lib/includes/hicn/protocol/ipv4.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017-2019 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 "../base.h"
+#include "../common.h"
+#include "../protocol.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;
+ u16 len;
+ u16 id;
+ u16 frag_off;
+ u8 ttl;
+ u8 protocol;
+ u16 csum;
+ ip4_address_t saddr;
+ ip4_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
+{
+ ip4_address_t ip_src;
+ ip4_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/includes/hicn/protocol/ipv6.h b/lib/includes/hicn/protocol/ipv6.h
new file mode 100644
index 000000000..5a83abcae
--- /dev/null
+++ b/lib/includes/hicn/protocol/ipv6.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019 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 "../common.h"
+
+/*
+ * The length of the IPV6 header struct must be 40 bytes.
+ */
+#define EXPECTED_IPV6_HDRLEN 40
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ 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 */
+ };
+ u8 vfc; /* 4 bits version, top 4 bits class */
+ };
+ ip6_address_t saddr; /* source address */
+ ip6_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
+{
+ ip6_address_t ip_src;
+ ip6_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/includes/hicn/protocol/tcp.h b/lib/includes/hicn/protocol/tcp.h
new file mode 100644
index 000000000..ded9a06b2
--- /dev/null
+++ b/lib/includes/hicn/protocol/tcp.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017-2019 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 "../base.h"
+#include "../common.h"
+#include "../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_pathlabel_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.");
+
+#ifndef HICN_VPP_PLUGIN
+
+/* 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_VPP_PLUGIN */
+
+// get_data_name_suffix
+// name->ip4.suffix = h->v4.tcp.seq;
+
+
+#endif /* HICN_PROTOCOL_TCP_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/includes/hicn/protocol/udp.h b/lib/includes/hicn/protocol/udp.h
new file mode 100644
index 000000000..75d1ea98c
--- /dev/null
+++ b/lib/includes/hicn/protocol/udp.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017-2019 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 length of the UDP header struct must be 8 bytes.
+ */
+#define EXPECTED_UDP_HDRLEN 8
+
+typedef struct
+{
+ u16 src_port;
+ u16 dst_port;
+ u16 length;
+ 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/includes/hicn/util/ip_address.h b/lib/includes/hicn/util/ip_address.h
new file mode 100644
index 000000000..728a9da90
--- /dev/null
+++ b/lib/includes/hicn/util/ip_address.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2017-2019 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 ip_address.h
+ * \brief IP address type
+ */
+#ifndef UTIL_IP_ADDRESS_H
+#define UTIL_IP_ADDRESS_H
+
+#include <arpa/inet.h> // inet_ntop
+#ifdef __APPLE__
+#include <libkern/OSByteOrder.h>
+#define __bswap_constant_32(x) OSSwapInt32(x)
+#include <machine/endian.h>
+#else
+#include <endian.h>
+#ifdef __ANDROID__
+#include <byteswap.h>
+#endif
+#include <endian.h>
+#endif
+#include <errno.h>
+#include <netdb.h> // struct addrinfo
+#ifndef _WIN32
+#include <netinet/in.h> // struct sockadd
+#endif
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h> // snprintf
+#include <string.h> // memset
+
+#include "types.h"
+
+#define bytes_to_bits(x) (x * 8)
+#define IPV6_ADDR_LEN 16 /* bytes */
+#define IPV4_ADDR_LEN 4 /* bytes */
+#define IPV6_ADDR_LEN_BITS bytes_to_bits(IPV6_ADDR_LEN)
+#define IPV4_ADDR_LEN_BITS bytes_to_bits(IPV4_ADDR_LEN)
+
+/* Presentation format */
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+//#define INET_MAX_ADDRSTRLEN INET6_ADDRSTRLEN
+
+#define IP_MAX_ADDR_LEN IPV6_ADDR_LEN
+
+#define DUMMY_PORT 1234
+
+typedef union {
+ union {
+ struct in_addr as_inaddr;
+ u8 as_u8[4];
+ u16 as_u16[2];
+ u32 as_u32;
+ } v4;
+ union {
+ struct in6_addr as_in6addr;
+ u8 as_u8[16];
+ u16 as_u16[8];
+ u32 as_u32[4];
+ u64 as_u64[2];
+ } v6;
+ u8 buffer[IP_MAX_ADDR_LEN];
+ u8 as_u8[IP_MAX_ADDR_LEN];
+ u16 as_u16[IP_MAX_ADDR_LEN >> 1];
+ u32 as_u32[IP_MAX_ADDR_LEN >> 2];
+ u64 as_u64[IP_MAX_ADDR_LEN >> 3];
+} ip_address_t;
+
+#define MAXSZ_IP4_ADDRESS_ INET_ADDRSTRLEN - 1
+#define MAXSZ_IP6_ADDRESS_ INET6_ADDRSTRLEN - 1
+#define MAXSZ_IP_ADDRESS_ MAXSZ_IP6_ADDRESS_
+#define MAXSZ_IP4_ADDRESS MAXSZ_IP4_ADDRESS_ + 1
+#define MAXSZ_IP6_ADDRESS MAXSZ_IP6_ADDRESS_ + 1
+#define MAXSZ_IP_ADDRESS MAXSZ_IP_ADDRESS_ + 1
+
+typedef struct {
+ int family;
+ ip_address_t address;
+ u8 len;
+} ip_prefix_t;
+
+#define MAXSZ_PREFIX_ MAXSZ_IP_ADDRESS_ + 1 + 3
+#define MAXSZ_PREFIX MAXSZ_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 ip_address_t IP_ADDRESS_EMPTY;
+
+#define IP_ANY(family) (family == AF_INET) ? IPV4_ANY : IPV6_ANY
+
+
+#define MAX_PORT 1 << (8 * sizeof(u16))
+#define IS_VALID_PORT(x) ((x > 0) && ((int)x < MAX_PORT))
+
+#define MAXSZ_PORT_ 5
+#define MAXSZ_PORT MAXSZ_PORT_ + 1
+
+#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 (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);
+
+/* Prefix */
+
+int ip_prefix_pton (const char *ip_address_str, ip_prefix_t * ip_prefix);
+int ip_prefix_ntop (const ip_prefix_t * ip_prefix, char *dst, size_t size);
+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);
+
+
+/* URL */
+
+#define MAXSZ_PROTO_ 8 /* inetX:// */
+#define MAXSZ_PROTO MAXSZ_PROTO_ + NULLTERM
+
+#define MAXSZ_URL4_ MAXSZ_PROTO_ + MAXSZ_IP4_ADDRESS_ + MAXSZ_PORT_
+#define MAXSZ_URL6_ MAXSZ_PROTO_ + MAXSZ_IP6_ADDRESS_ + MAXSZ_PORT_
+#define MAXSZ_URL_ MAXSZ_URL6_
+#define MAXSZ_URL4 MAXSZ_URL4_ + NULLTERM
+#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);
+
+#endif /* UTIL_IP_ADDRESS_H */
diff --git a/lib/includes/hicn/util/token.h b/lib/includes/hicn/util/token.h
new file mode 100644
index 000000000..43e0a77b2
--- /dev/null
+++ b/lib/includes/hicn/util/token.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017-2019 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.
+ */
+
+/* Token concatenation */
+
+/*
+ * Concatenate preprocessor tokens A and B without expanding macro definitions
+ * (however, if invoked from a macro, macro arguments are expanded).
+ */
+#define PPCAT_NX(A, B) A ## B
+
+/*
+ * Concatenate preprocessor tokens A and B after macro-expanding them.
+ */
+#define PPCAT(A, B) PPCAT_NX(A, B)
+
+/* Token stringification */
+
+/*
+ * Turn A into a string literal without expanding macro definitions
+ * (however, if invoked from a macro, macro arguments are expanded).
+ */
+#define STRINGIZE_NX(A) #A
+
+/*
+ * Turn A into a string literal after macro-expanding it.
+ */
+#define STRINGIZE(A) STRINGIZE_NX(A)
diff --git a/lib/includes/hicn/util/types.h b/lib/includes/hicn/util/types.h
new file mode 100644
index 000000000..50b368b8d
--- /dev/null
+++ b/lib/includes/hicn/util/types.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017-2019 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 UTIL_TYPES
+#define UTIL_TYPES
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+/* Helper for avoiding warnings about type-punning */
+#define UNION_CAST(x, destType) \
+ (((union {__typeof__(x) a; destType b;})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))
+
+#endif /* UTIL_TYPES */