From 6b84ec54083da9911f5ad4816d0eb4f4745afad4 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Mon, 7 Oct 2019 09:52:33 +0200 Subject: [HICN-298] Release new hICN app for Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I43adc62fadf00690b687078d739788dffdc5e566 Signed-off-by: Jordan Augé --- lib/CMakeLists.txt | 1 + lib/includes/CMakeLists.txt | 55 ++++ lib/includes/hicn/base.h | 161 +++++++++ lib/includes/hicn/common.h | 316 ++++++++++++++++++ lib/includes/hicn/compat.h | 461 ++++++++++++++++++++++++++ lib/includes/hicn/error.h | 58 ++++ lib/includes/hicn/header.h | 129 ++++++++ lib/includes/hicn/hicn.h | 79 +++++ lib/includes/hicn/mapme.h | 162 +++++++++ lib/includes/hicn/name.h | 295 +++++++++++++++++ lib/includes/hicn/ops.h | 641 ++++++++++++++++++++++++++++++++++++ lib/includes/hicn/policy.h | 242 ++++++++++++++ lib/includes/hicn/protocol.h | 51 +++ lib/includes/hicn/protocol/ah.h | 80 +++++ lib/includes/hicn/protocol/icmp.h | 84 +++++ lib/includes/hicn/protocol/icmprd.h | 72 ++++ lib/includes/hicn/protocol/ipv4.h | 105 ++++++ lib/includes/hicn/protocol/ipv6.h | 80 +++++ lib/includes/hicn/protocol/tcp.h | 173 ++++++++++ lib/includes/hicn/protocol/udp.h | 44 +++ lib/includes/hicn/util/ip_address.h | 159 +++++++++ lib/includes/hicn/util/token.h | 40 +++ lib/includes/hicn/util/types.h | 36 ++ lib/src/CMakeLists.txt | 63 +--- lib/src/base.h | 161 --------- lib/src/common.c | 3 +- lib/src/common.h | 316 ------------------ lib/src/compat.c | 44 +-- lib/src/compat.h | 461 -------------------------- lib/src/error.c | 2 +- lib/src/error.h | 58 ---- lib/src/header.h | 129 -------- lib/src/hicn.h | 79 ----- lib/src/mapme.c | 10 +- lib/src/mapme.h | 162 --------- lib/src/name.c | 161 ++------- lib/src/name.h | 343 ------------------- lib/src/ops.c | 4 +- lib/src/ops.h | 641 ------------------------------------ lib/src/policy.c | 59 ++++ lib/src/protocol.h | 51 --- lib/src/protocol/ah.c | 10 +- lib/src/protocol/ah.h | 80 ----- lib/src/protocol/icmp.c | 6 +- lib/src/protocol/icmp.h | 84 ----- lib/src/protocol/icmprd.h | 72 ---- lib/src/protocol/ipv4.c | 10 +- lib/src/protocol/ipv4.h | 105 ------ lib/src/protocol/ipv6.c | 6 +- lib/src/protocol/ipv6.h | 80 ----- lib/src/protocol/tcp.c | 6 +- lib/src/protocol/tcp.h | 173 ---------- lib/src/protocol/udp.h | 44 --- lib/src/util/ip_address.c | 315 ++++++++++++++++++ 54 files changed, 3981 insertions(+), 3281 deletions(-) create mode 100644 lib/includes/CMakeLists.txt create mode 100644 lib/includes/hicn/base.h create mode 100644 lib/includes/hicn/common.h create mode 100644 lib/includes/hicn/compat.h create mode 100644 lib/includes/hicn/error.h create mode 100644 lib/includes/hicn/header.h create mode 100644 lib/includes/hicn/hicn.h create mode 100644 lib/includes/hicn/mapme.h create mode 100644 lib/includes/hicn/name.h create mode 100644 lib/includes/hicn/ops.h create mode 100644 lib/includes/hicn/policy.h create mode 100644 lib/includes/hicn/protocol.h create mode 100644 lib/includes/hicn/protocol/ah.h create mode 100644 lib/includes/hicn/protocol/icmp.h create mode 100644 lib/includes/hicn/protocol/icmprd.h create mode 100644 lib/includes/hicn/protocol/ipv4.h create mode 100644 lib/includes/hicn/protocol/ipv6.h create mode 100644 lib/includes/hicn/protocol/tcp.h create mode 100644 lib/includes/hicn/protocol/udp.h create mode 100644 lib/includes/hicn/util/ip_address.h create mode 100644 lib/includes/hicn/util/token.h create mode 100644 lib/includes/hicn/util/types.h delete mode 100644 lib/src/base.h delete mode 100644 lib/src/common.h delete mode 100644 lib/src/compat.h delete mode 100644 lib/src/error.h delete mode 100644 lib/src/header.h delete mode 100644 lib/src/hicn.h delete mode 100644 lib/src/mapme.h delete mode 100644 lib/src/name.h delete mode 100644 lib/src/ops.h create mode 100644 lib/src/policy.c delete mode 100644 lib/src/protocol.h delete mode 100644 lib/src/protocol/ah.h delete mode 100644 lib/src/protocol/icmp.h delete mode 100644 lib/src/protocol/icmprd.h delete mode 100644 lib/src/protocol/ipv4.h delete mode 100644 lib/src/protocol/ipv6.h delete mode 100644 lib/src/protocol/tcp.h delete mode 100644 lib/src/protocol/udp.h create mode 100644 lib/src/util/ip_address.c (limited to 'lib') diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 9d8267f5f..4df09c0dd 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -46,6 +46,7 @@ else () set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4996") endif () +add_subdirectory(includes) add_subdirectory (src) add_subdirectory (doc) 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 +#include + +/* 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 +#include +#include +#include +#include + +#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 // ip4_address_t +#include // ip6_address_t + +#else + + +#ifndef _WIN32 +#include +#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 +#include +#include +#include + +#else + +#include +#include +#include +#include +#include +#include + +#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 // u32 +#include + +#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 +#ifndef _WIN32 +#include // struct sockadd +#endif +#include +#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 + +#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 // INET*_ADDRSTRLEN +#include // strcasecmp +#include + +/* 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 // inet_ntop +#ifdef __APPLE__ +#include +#define __bswap_constant_32(x) OSSwapInt32(x) +#include +#else +#include +#ifdef __ANDROID__ +#include +#endif +#include +#endif +#include +#include // struct addrinfo +#ifndef _WIN32 +#include // struct sockadd +#endif +#include +#include +#include // snprintf +#include // 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 */ diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt index 65eae8d77..d8c7b11e0 100644 --- a/lib/src/CMakeLists.txt +++ b/lib/src/CMakeLists.txt @@ -13,41 +13,20 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) -list(APPEND LIBHICN_HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/hicn.h - ${CMAKE_CURRENT_SOURCE_DIR}/base.h - ${CMAKE_CURRENT_SOURCE_DIR}/common.h - ${CMAKE_CURRENT_SOURCE_DIR}/compat.h - ${CMAKE_CURRENT_SOURCE_DIR}/error.h - ${CMAKE_CURRENT_SOURCE_DIR}/header.h - ${CMAKE_CURRENT_SOURCE_DIR}/mapme.h - ${CMAKE_CURRENT_SOURCE_DIR}/name.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol.h - ${CMAKE_CURRENT_SOURCE_DIR}/ops.h -) - -list(APPEND LIBHICN_HEADER_FILES_PROTOCOL - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ah.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/icmp.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/icmprd.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ipv4.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ipv6.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/tcp.h - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/udp.h -) - list(APPEND LIBHICN_SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/common.c ${CMAKE_CURRENT_SOURCE_DIR}/compat.c ${CMAKE_CURRENT_SOURCE_DIR}/error.c ${CMAKE_CURRENT_SOURCE_DIR}/mapme.c ${CMAKE_CURRENT_SOURCE_DIR}/name.c ${CMAKE_CURRENT_SOURCE_DIR}/ops.c - ${CMAKE_CURRENT_SOURCE_DIR}/common.c + ${CMAKE_CURRENT_SOURCE_DIR}/policy.c ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ah.c ${CMAKE_CURRENT_SOURCE_DIR}/protocol/icmp.c ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ipv4.c ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ipv6.c ${CMAKE_CURRENT_SOURCE_DIR}/protocol/tcp.c + ${CMAKE_CURRENT_SOURCE_DIR}/util/ip_address.c ) set (COMPILER_DEFINITIONS "-DWITH_MAPME") @@ -55,48 +34,26 @@ set (COMPILER_DEFINITIONS "-DWITH_MAPME") include(BuildMacros) include(WindowsMacros) -if (ANDROID_API) +if (${CMAKE_SYSTEM_NAME} STREQUAL "Android") build_library(${LIBHICN} STATIC - SOURCES ${LIBHICN_SOURCE_FILES} ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} + SOURCES ${LIBHICN_SOURCE_FILES} ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} ${LIBHICN_HEADER_FILES_UTIL} COMPONENT lib${LIBHICN} - INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. + INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../includes DEFINITIONS ${COMPILER_DEFINITIONS} INSTALL_ROOT_DIR hicn - INSTALL_HEADERS ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} + INSTALL_HEADERS ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} ${LIBHICN_HEADER_FILES_UTIL} LINK_LIBRARIES ${WSOCK32_LIBRARY} ${WS2_32_LIBRARY} ) else () build_library(${LIBHICN} SHARED STATIC - SOURCES ${LIBHICN_SOURCE_FILES} ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} + SOURCES ${LIBHICN_SOURCE_FILES} ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} ${LIBHICN_HEADER_FILES_UTIL} COMPONENT lib${LIBHICN} - INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. + INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../includes DEFINITIONS ${COMPILER_DEFINITIONS} INSTALL_ROOT_DIR hicn - INSTALL_HEADERS ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} + INSTALL_HEADERS ${LIBHICN_HEADER_FILES} ${LIBHICN_HEADER_FILES_PROTOCOL} ${LIBHICN_HEADER_FILES_UTIL} LINK_LIBRARIES ${WSOCK32_LIBRARY} ${WS2_32_LIBRARY} ) endif () -add_custom_command(TARGET ${LIBHICN_STATIC} PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/hicn -) - -add_custom_command(TARGET ${LIBHICN_STATIC} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/hicn/ - COMMAND ${CMAKE_COMMAND} -E copy ${LIBHICN_HEADER_FILES} ${CMAKE_BINARY_DIR}/hicn/ -) - -add_custom_command(TARGET ${LIBHICN_STATIC} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/hicn/protocol - COMMAND ${CMAKE_COMMAND} -E copy ${LIBHICN_HEADER_FILES_PROTOCOL} ${CMAKE_BINARY_DIR}/hicn/protocol -) - -set(HICN_INCLUDE_DIRS - ${CMAKE_BINARY_DIR} "" - CACHE INTERNAL - "" FORCE -) - -# install(FILES ${LIBHICN_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/hicn COMPONENT libhicn) -# install(FILES ${LIBHICN_HEADER_FILES_PROTOCOL} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/hicn/protocol COMPONENT libhicn) diff --git a/lib/src/base.h b/lib/src/base.h deleted file mode 100644 index d8a79a9c2..000000000 --- a/lib/src/base.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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/src/common.c b/lib/src/common.c index de4ece339..78d25b770 100644 --- a/lib/src/common.c +++ b/lib/src/common.c @@ -28,7 +28,8 @@ #endif #include -#include "common.h" +#include + int diff --git a/lib/src/common.h b/lib/src/common.h deleted file mode 100644 index 33323da1b..000000000 --- a/lib/src/common.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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 -#include - -/* 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 -#include -#include -#include -#include - -#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 // ip4_address_t -#include // ip6_address_t - -#else - - -#ifndef _WIN32 -#include -#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/src/compat.c b/lib/src/compat.c index 633037a0f..9834b9d44 100644 --- a/lib/src/compat.c +++ b/lib/src/compat.c @@ -23,12 +23,12 @@ #include // memset #include // offsetof -#include "common.h" -#include "compat.h" -#include "error.h" -#include "header.h" -#include "name.h" -#include "ops.h" +#include +#include +#include +#include +#include +#include #define member_size(type, member) sizeof(((type *)0)->member) #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) @@ -319,7 +319,7 @@ hicn_packet_get_payload (hicn_format_t format, const hicn_header_t * h, int hicn_packet_get_locator (hicn_format_t format, const hicn_header_t * h, - ip_address_t * ip_address, bool is_interest) + ip_prefix_t * prefix, bool is_interest) { const void *locator; int is_ipv4 = (format & HFO_INET); @@ -328,28 +328,28 @@ hicn_packet_get_locator (hicn_format_t format, const hicn_header_t * h, if (is_ipv4) { locator = is_interest ? &h->v4.ip.saddr : &h->v4.ip.daddr; - ip_address->family = AF_INET; - ip_address->prefix_len = IPV4_ADDR_LEN_BITS; + prefix->family = AF_INET; + prefix->len = IPV4_ADDR_LEN_BITS; } else if (is_ipv6) { locator = is_interest ? &h->v6.ip.saddr : &h->v6.ip.daddr; - ip_address->family = AF_INET6; - ip_address->prefix_len = IPV6_ADDR_LEN_BITS; + prefix->family = AF_INET6; + prefix->len = IPV6_ADDR_LEN_BITS; } else { return HICN_LIB_ERROR_NOT_IMPLEMENTED; } - memcpy (ip_address->buffer, locator, ip_address_len (ip_address)); + memcpy (prefix->address.buffer, locator, ip_prefix_len(prefix)); return HICN_LIB_ERROR_NONE; } int hicn_packet_set_locator (hicn_format_t format, hicn_header_t * h, - const ip_address_t * ip_address, bool is_interest) + const ip_prefix_t * prefix, bool is_interest) { void *locator; int is_ipv4 = (format & HFO_INET); @@ -368,7 +368,7 @@ hicn_packet_set_locator (hicn_format_t format, hicn_header_t * h, return HICN_LIB_ERROR_INVALID_PARAMETER; } - memcpy (locator, ip_address->buffer, ip_address_len (ip_address)); + memcpy (locator, prefix->address.buffer, ip_prefix_len(prefix)); return HICN_LIB_ERROR_NONE; } @@ -951,16 +951,16 @@ hicn_interest_set_name (hicn_format_t format, hicn_header_t * interest, int hicn_interest_get_locator (hicn_format_t format, const hicn_header_t * interest, - ip_address_t * ip_address) + ip_prefix_t * prefix) { - return hicn_packet_get_locator (format, interest, ip_address, _INTEREST); + return hicn_packet_get_locator (format, interest, prefix, _INTEREST); } int hicn_interest_set_locator (hicn_format_t format, hicn_header_t * interest, - const ip_address_t * ip_address) + const ip_prefix_t * prefix) { - return hicn_packet_set_locator (format, interest, ip_address, _INTEREST); + return hicn_packet_set_locator (format, interest, prefix, _INTEREST); } int @@ -1043,16 +1043,16 @@ hicn_data_set_name (hicn_format_t format, hicn_header_t * data, int hicn_data_get_locator (hicn_format_t format, const hicn_header_t * data, - ip_address_t * ip_address) + ip_prefix_t * prefix) { - return hicn_packet_get_locator (format, data, ip_address, _DATA); + return hicn_packet_get_locator (format, data, prefix, _DATA); } int hicn_data_set_locator (hicn_format_t format, hicn_header_t * data, - const ip_address_t * ip_address) + const ip_prefix_t * prefix) { - return hicn_packet_set_locator (format, data, ip_address, _DATA); + return hicn_packet_set_locator (format, data, prefix, _DATA); } int diff --git a/lib/src/compat.h b/lib/src/compat.h deleted file mode 100644 index 7228843bb..000000000 --- a/lib/src/compat.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - * 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_address_t * ip_address, bool is_interest); - -/** - * @brief Sets the locator of an interest / data packet - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @param [out] ip_address - retrieved locator - * @param [in] is_interest - Flag to determine whether it is an interest (1) or - * data packet (0) - * @return hICN error code - */ -int hicn_packet_set_locator (hicn_format_t format, hicn_header_t * packet, - const ip_address_t * ip_address, - 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_address_t * ip_address); -int hicn_interest_set_locator (hicn_format_t format, hicn_header_t * interest, - const ip_address_t * ip_address); -int hicn_interest_compare (const hicn_header_t * interest_1, - const hicn_header_t * interest_2); -int hicn_interest_set_lifetime (hicn_header_t * interest, u32 lifetime); -int hicn_interest_get_lifetime (const hicn_header_t * interest, - u32 * lifetime); -int hicn_interest_get_header_length (hicn_format_t format, - const hicn_header_t * interest, - size_t * header_length); -int hicn_interest_get_payload_length (hicn_format_t format, - const hicn_header_t * interest, - size_t * payload_length); -int hicn_interest_set_payload (hicn_format_t format, hicn_header_t * interest, - const u8 * payload, size_t payload_length); -int hicn_interest_get_payload (hicn_format_t format, - const hicn_header_t * interest, u8 ** payload, - size_t * payload_size, bool hard_copy); -int hicn_interest_reset_for_hash (hicn_format_t format, - hicn_header_t * packet); - -/* Data */ - -int hicn_data_get_name (hicn_format_t format, const hicn_header_t * data, - hicn_name_t * name); -int hicn_data_set_name (hicn_format_t format, hicn_header_t * data, - const hicn_name_t * name); -int hicn_data_get_locator (hicn_format_t format, const hicn_header_t * data, - ip_address_t * ip_address); -int hicn_data_set_locator (hicn_format_t format, hicn_header_t * data, - const ip_address_t * ip_address); -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/src/error.c b/lib/src/error.c index 865e2b47d..ab5d6e27d 100644 --- a/lib/src/error.c +++ b/lib/src/error.c @@ -18,7 +18,7 @@ * @brief Implementation of error management functions. */ -#include "error.h" +#include const char *HICN_LIB_ERROR_STRING[] = { #define _(a,b,c) [b] = c, diff --git a/lib/src/error.h b/lib/src/error.h deleted file mode 100644 index 3e027c4e5..000000000 --- a/lib/src/error.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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/src/header.h b/lib/src/header.h deleted file mode 100644 index b21fe5c84..000000000 --- a/lib/src/header.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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/src/hicn.h b/lib/src/hicn.h deleted file mode 100644 index 749fd4247..000000000 --- a/lib/src/hicn.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 -#include -#include -#include - -#else - -#include -#include -#include -#include -#include -#include - -#endif - -#endif /* HICN__H */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/lib/src/mapme.c b/lib/src/mapme.c index ccd384b21..3e7e8bc80 100644 --- a/lib/src/mapme.c +++ b/lib/src/mapme.c @@ -18,12 +18,12 @@ * @brief Implementation of MAP-Me anchorless producer mobility management. */ -#include "mapme.h" -#include "common.h" -#include "error.h" +#include +#include +#include -#include "protocol/ipv4.h" -#include "protocol/ipv6.h" +#include +#include size_t hicn_mapme_v4_create_packet (u8 * buf, const hicn_prefix_t * prefix, diff --git a/lib/src/mapme.h b/lib/src/mapme.h deleted file mode 100644 index 8fae44530..000000000 --- a/lib/src/mapme.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 // u32 -#include - -#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/src/name.c b/lib/src/name.c index 0a0da63cf..1f1051522 100644 --- a/lib/src/name.c +++ b/lib/src/name.c @@ -26,11 +26,9 @@ #include // strtoul #include // memcpy -#include "common.h" -#include "error.h" -#include "name.h" - -#define DUMMY_PORT ntohs(1234) +#include +#include +#include #if ! HICN_VPP_PLUGIN int @@ -76,10 +74,10 @@ hicn_name_create (const char *ip_address, u32 id, hicn_name_t * name) } int -hicn_name_create_from_ip_address (const ip_address_t * ip_address, u32 id, +hicn_name_create_from_prefix (const ip_prefix_t * prefix, u32 id, hicn_name_t * name) { - switch (ip_address->family) + switch (prefix->family) { case AF_INET: name->type = HNT_CONTIGUOUS_V4; @@ -91,13 +89,13 @@ hicn_name_create_from_ip_address (const ip_address_t * ip_address, u32 id, return HICN_LIB_ERROR_INVALID_IP_ADDRESS; } - name->len = (u8) ip_address_len (ip_address); + name->len = (u8) (prefix->len); if ((name->type != HNT_CONTIGUOUS_V4) && (name->type != HNT_CONTIGUOUS_V6)) { return HICN_LIB_ERROR_NOT_IMPLEMENTED; } - memcpy (name->buffer, ip_address->buffer, name->len); + memcpy (name->buffer, prefix->address.buffer, ip_prefix_len (prefix)); *(u32 *) (name->buffer + name->len) = id; return HICN_LIB_ERROR_NONE; @@ -391,27 +389,27 @@ hicn_name_to_sockaddr_address (const hicn_name_t * name, } int -hicn_name_to_ip_address (const hicn_name_t * name, ip_address_t * ip_address) +hicn_name_to_ip_prefix (const hicn_name_t * name, ip_prefix_t * prefix) { switch (name->type) { case HNT_CONTIGUOUS_V6: - memcpy (&ip_address->buffer, name->buffer, IPV6_ADDR_LEN); - ip_address->family = AF_INET6; + memcpy (&prefix->address.buffer, name->buffer, IPV6_ADDR_LEN); + prefix->family = AF_INET6; break; case HNT_IOV_V6: - memcpy (&ip_address->buffer, name->iov.buffers[0].iov_base, + memcpy (&prefix->address.buffer, name->iov.buffers[0].iov_base, name->iov.buffers[0].iov_len); - ip_address->family = AF_INET6; + prefix->family = AF_INET6; break; case HNT_CONTIGUOUS_V4: - memcpy (&ip_address->buffer, name->buffer, IPV4_ADDR_LEN); - ip_address->family = AF_INET; + memcpy (&prefix->address.buffer, name->buffer, IPV4_ADDR_LEN); + prefix->family = AF_INET; break; case HNT_IOV_V4: - memcpy (&ip_address->buffer, name->iov.buffers[0].iov_base, + memcpy (&prefix->address.buffer, name->iov.buffers[0].iov_base, name->iov.buffers[0].iov_len); - ip_address->family = AF_INET; + prefix->family = AF_INET; break; default: return HICN_LIB_ERROR_UNEXPECTED; @@ -525,143 +523,28 @@ hicn_name_get_family (const hicn_name_t * name, int *family) } int -hicn_prefix_create_from_ip_address (const ip_address_t * ip_address, +hicn_prefix_create_from_ip_prefix (const ip_prefix_t * ip_prefix, hicn_prefix_t * prefix) { - switch (ip_address->family) + switch (ip_prefix->family) { case AF_INET: - prefix->name.ip4.as_u32 = ip_address->as_u32[0]; + prefix->name.ip4.as_u32 = ip_prefix->address.as_u32[0]; break; case AF_INET6: - prefix->name.ip6.as_u64[0] = ip_address->as_u64[0]; - prefix->name.ip6.as_u64[1] = ip_address->as_u64[1]; + prefix->name.ip6.as_u64[0] = ip_prefix->address.as_u64[0]; + prefix->name.ip6.as_u64[1] = ip_prefix->address.as_u64[1]; break; default: return HICN_LIB_ERROR_INVALID_IP_ADDRESS; } - prefix->len = (u8) (ip_address->prefix_len); + prefix->len = (u8) (ip_prefix->len); return HICN_LIB_ERROR_NONE; } #endif /* ! HICN_VPP_PLUGIN */ -/******** - * IP - */ - -inline int -ip_address_len (const ip_address_t * ip_address) -{ - return (ip_address->family == AF_INET6) ? IPV6_ADDR_LEN : - (ip_address->family == AF_INET) ? IPV4_ADDR_LEN : 0; -} - -bool -ip_address_empty (const ip_address_t * ip_address) -{ - return ip_address->prefix_len == 0; -} - -int -hicn_ip_ntop (const ip_address_t * ip_address, char *dst, const size_t len) -{ - const char *rc; - - rc = inet_ntop (ip_address->family, ip_address->buffer, dst, len); - if (!rc) - { - printf ("error ntop: %d %s\n", errno, strerror (errno)); - return HICN_LIB_ERROR_INVALID_IP_ADDRESS; - } - - return HICN_LIB_ERROR_NONE; -} - -/* - * Parse ip addresses in presentation format, or prefixes (in bits, separated by a slash) - */ -int -hicn_ip_pton (const char *ip_address_str, ip_address_t * ip_address) -{ - int pton_fd; - char *p; - char *eptr; - u32 dst_len; - char *addr = strdup (ip_address_str); - - p = strchr (addr, '/'); - if (!p) - { - dst_len = 0; // until we get the ip address family - } - else - { - dst_len = strtoul (p + 1, &eptr, 10); - *p = 0; - } - - ip_address->family = get_addr_family (addr); - - switch (ip_address->family) - { - case AF_INET6: - if (dst_len > IPV6_ADDR_LEN_BITS) - goto ERR; - pton_fd = inet_pton (AF_INET6, addr, &ip_address->buffer); - ip_address->prefix_len = dst_len ? dst_len : IPV6_ADDR_LEN_BITS; - break; - case AF_INET: - if (dst_len > IPV4_ADDR_LEN_BITS) - goto ERR; - pton_fd = inet_pton (AF_INET, addr, &ip_address->buffer); - ip_address->prefix_len = dst_len ? dst_len : IPV4_ADDR_LEN_BITS; - break; - default: - goto ERR; - } - - // 0 = not in presentation format - // < 0 = other error (use perror) - if (pton_fd <= 0) - { - goto ERR; - } - - return HICN_LIB_ERROR_NONE; -ERR: - free (addr); - return HICN_LIB_ERROR_INVALID_IP_ADDRESS; -} - -int -hicn_ip_to_sockaddr_address (const ip_address_t * ip_address, - struct sockaddr *sockaddr_address) -{ - struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *) sockaddr_address; - struct sockaddr_in *tmp4 = (struct sockaddr_in *) sockaddr_address; - - switch (ip_address->family) - { - case AF_INET6: - tmp6->sin6_family = AF_INET6; - tmp6->sin6_port = DUMMY_PORT; - tmp6->sin6_scope_id = 0; - memcpy (&tmp6->sin6_addr, ip_address->buffer, IPV6_ADDR_LEN); - break; - case AF_INET: - tmp4->sin_family = AF_INET; - tmp4->sin_port = DUMMY_PORT; - memcpy (&tmp4->sin_addr, ip_address->buffer, IPV4_ADDR_LEN); - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - - return HICN_LIB_ERROR_NONE; -} - /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/name.h b/lib/src/name.h deleted file mode 100644 index 434b563b8..000000000 --- a/lib/src/name.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * 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 -#ifndef _WIN32 -#include // struct sockadd -#endif -#include "common.h" - -/****************************************************************************** - * IP address helpers - ******************************************************************************/ - -/* Presentation format */ -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 -#endif -//#define INET_MAX_ADDRSTRLEN INET6_ADDRSTRLEN - -/* Address size */ -#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) - -#define IP_MAX_ADDR_LEN IPV6_ADDR_LEN -#define TCP_SEQNO_LEN 4 /* bytes */ - -struct ip_address -{ - union - { - 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]; - ip46_address_t as_ip46; - }; - int family; - unsigned short prefix_len; -}; - -typedef struct ip_address ip_address_t; - -int ip_address_len (const ip_address_t * ip_address); -bool ip_address_empty (const ip_address_t * ip_address); - -int hicn_ip_ntop (const ip_address_t * ip_address, char *dst, - const size_t len); -int hicn_ip_pton (const char *ip_address_str, ip_address_t * ip_address); -int hicn_ip_to_sockaddr_address (const ip_address_t * ip_address, - struct sockaddr *sockaddr_address); - -/****************************************************************************** - * hICN names - ******************************************************************************/ - -#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_address (const ip_address_t * ip_address, 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_address (const hicn_name_t * name, - ip_address_t * ip_address); - -/** - * @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_address (const ip_address_t * ip_address, - 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/src/ops.c b/lib/src/ops.c index 3e272572a..9bb78be65 100644 --- a/lib/src/ops.c +++ b/lib/src/ops.c @@ -22,9 +22,9 @@ #include #endif #include -#include "ops.h" +#include -#include "header.h" +#include extern const hicn_ops_t hicn_ops_ipv4; extern const hicn_ops_t hicn_ops_icmp; diff --git a/lib/src/ops.h b/lib/src/ops.h deleted file mode 100644 index 47795efd5..000000000 --- a/lib/src/ops.h +++ /dev/null @@ -1,641 +0,0 @@ -/* - * 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 - -#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/src/policy.c b/lib/src/policy.c new file mode 100644 index 000000000..336249bbb --- /dev/null +++ b/lib/src/policy.c @@ -0,0 +1,59 @@ +/* + * 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 Implementation of policy description + */ + +#include +#include + +const char * policy_tag_str[] = { + #define _(x, y) [POLICY_TAG_ ## x] = STRINGIZE(x), + foreach_policy_tag + #undef _ +}; + +const char policy_tag_short_str[] = { + #define _(x, y) [POLICY_TAG_ ## x] = y, + foreach_policy_tag + #undef _ +}; + +const char * policy_state_str[] = { + #define _(x) [POLICY_STATE_ ## x] = STRINGIZE(x), + foreach_policy_state + #undef _ +}; + +int +policy_tag_state_snprintf(char * s, size_t size, const policy_tag_state_t * tag_state) +{ + char *cur = s; + int rc; + + if (tag_state->disabled > 1) + return -1; + + rc = snprintf(cur, s + size - cur, "%s%s", (tag_state->disabled == 1) ? "!" : "", policy_state_str[tag_state->state]); + if (rc < 0) + return rc; + cur += rc; + if (size != 0 && cur >= s + size) + return cur - s; + + return cur - s; +} diff --git a/lib/src/protocol.h b/lib/src/protocol.h deleted file mode 100644 index a97cc99cf..000000000 --- a/lib/src/protocol.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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/src/protocol/ah.c b/lib/src/protocol/ah.c index 5a30f66f6..c2f3f552a 100644 --- a/lib/src/protocol/ah.c +++ b/lib/src/protocol/ah.c @@ -19,11 +19,11 @@ */ #include // memcpy -#include "../common.h" -#include "../error.h" -#include "../header.h" -#include "../ops.h" -#include "ah.h" +#include +#include +#include +#include +#include DECLARE_get_interest_locator (ah, UNEXPECTED); DECLARE_set_interest_locator (ah, UNEXPECTED); diff --git a/lib/src/protocol/ah.h b/lib/src/protocol/ah.h deleted file mode 100644 index a59a5051a..000000000 --- a/lib/src/protocol/ah.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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/src/protocol/icmp.c b/lib/src/protocol/icmp.c index 45a28959c..85605a2c3 100644 --- a/lib/src/protocol/icmp.c +++ b/lib/src/protocol/icmp.c @@ -14,10 +14,10 @@ */ #include -#include "icmp.h" +#include -#include "../error.h" -#include "../ops.h" +#include +#include DECLARE_get_interest_locator (icmp, UNEXPECTED) DECLARE_set_interest_locator (icmp, UNEXPECTED) diff --git a/lib/src/protocol/icmp.h b/lib/src/protocol/icmp.h deleted file mode 100644 index 36954bb6d..000000000 --- a/lib/src/protocol/icmp.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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/src/protocol/icmprd.h b/lib/src/protocol/icmprd.h deleted file mode 100644 index aa1fa01ae..000000000 --- a/lib/src/protocol/icmprd.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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/src/protocol/ipv4.c b/lib/src/protocol/ipv4.c index 3c82b3223..d8d958350 100644 --- a/lib/src/protocol/ipv4.c +++ b/lib/src/protocol/ipv4.c @@ -27,12 +27,12 @@ #include #include -#include "../error.h" -#include "../ops.h" -#include "../common.h" -#include "../header.h" +#include +#include +#include +#include -#include "ipv4.h" +#include int ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t * h, size_t * payload_length); diff --git a/lib/src/protocol/ipv4.h b/lib/src/protocol/ipv4.h deleted file mode 100644 index 8a5b6683b..000000000 --- a/lib/src/protocol/ipv4.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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/src/protocol/ipv6.c b/lib/src/protocol/ipv6.c index 7554eadf2..622355294 100644 --- a/lib/src/protocol/ipv6.c +++ b/lib/src/protocol/ipv6.c @@ -16,9 +16,9 @@ #include #include -#include "../common.h" -#include "../error.h" -#include "../ops.h" +#include +#include +#include int ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t * h, diff --git a/lib/src/protocol/ipv6.h b/lib/src/protocol/ipv6.h deleted file mode 100644 index 5a83abcae..000000000 --- a/lib/src/protocol/ipv6.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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/src/protocol/tcp.c b/lib/src/protocol/tcp.c index b9f1d2775..0e3155020 100644 --- a/lib/src/protocol/tcp.c +++ b/lib/src/protocol/tcp.c @@ -14,10 +14,10 @@ */ #include -#include "tcp.h" +#include -#include "../error.h" -#include "../ops.h" +#include +#include #define TCP_DEFAULT_SRC_PORT 0x8000 #define TCP_DEFAULT_DST_PORT 0x0080 diff --git a/lib/src/protocol/tcp.h b/lib/src/protocol/tcp.h deleted file mode 100644 index ded9a06b2..000000000 --- a/lib/src/protocol/tcp.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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/src/protocol/udp.h b/lib/src/protocol/udp.h deleted file mode 100644 index 75d1ea98c..000000000 --- a/lib/src/protocol/udp.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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/src/util/ip_address.c b/lib/src/util/ip_address.c new file mode 100644 index 000000000..ea238167f --- /dev/null +++ b/lib/src/util/ip_address.c @@ -0,0 +1,315 @@ +/* + * 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.c + * \brief Implementation of IP address type + */ + +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#ifdef __ANDROID__ +#define SWAP(x) bswap_32(x) +#else +#define SWAP(x) __bswap_constant_32(x) +#endif +#else +#define SWAP(x) x +#endif + + +/* No htonl() with const */ +const ip_address_t IPV4_LOOPBACK = (ip_address_t) { + .v4.as_inaddr.s_addr = SWAP(INADDR_LOOPBACK), +}; + +const ip_address_t IPV6_LOOPBACK = (ip_address_t) { + .v6.as_in6addr = IN6ADDR_LOOPBACK_INIT, +}; + +const ip_address_t IPV4_ANY = (ip_address_t) { + .v4.as_inaddr.s_addr = INADDR_ANY, +}; + +const ip_address_t IPV6_ANY = (ip_address_t) { + .v6.as_in6addr = IN6ADDR_ANY_INIT, +}; + +const ip_address_t IP_ADDRESS_EMPTY = { + .as_u64 = { 0 }, +}; + + +/* IP address */ + +int +ip_address_get_family (const char * ip_address) +{ + struct addrinfo hint, *res = NULL; + int rc; + + memset (&hint, '\0', sizeof hint); + + hint.ai_family = PF_UNSPEC; + hint.ai_flags = AI_NUMERICHOST; + + rc = getaddrinfo (ip_address, NULL, &hint, &res); + if (rc) + { + return -1; + } + rc = res->ai_family; + freeaddrinfo (res); + return rc; +} + +int +ip_address_len (const ip_address_t * ip_address, int family) +{ + return (family == AF_INET6) ? IPV6_ADDR_LEN : + (family == AF_INET) ? IPV4_ADDR_LEN : 0; +} + +int +ip_address_ntop (const ip_address_t * ip_address, char *dst, const size_t len, + int family) +{ + const char * s = inet_ntop (family, ip_address->buffer, dst, len); + return (s ? 1 : -1); +} + +/* + * Parse ip addresses in presentation format + */ +int +ip_address_pton (const char *ip_address_str, ip_address_t * ip_address) +{ + int pton_fd; + char *addr = strdup (ip_address_str); + int family; + + + family = ip_address_get_family (addr); + + switch (family) + { + case AF_INET6: + pton_fd = inet_pton (AF_INET6, addr, &ip_address->buffer); + break; + case AF_INET: + pton_fd = inet_pton (AF_INET, addr, &ip_address->buffer); + break; + default: + goto ERR; + } + + // 0 = not in presentation format + // < 0 = other error (use perror) + if (pton_fd <= 0) + { + goto ERR; + } + + return 1; +ERR: + free (addr); + return -1; +} + +int +ip_address_snprintf(char * s, size_t size, const ip_address_t * ip_address, int family) +{ + size_t len = family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN; + const char * rc = inet_ntop (family, ip_address->buffer, s, len); + return rc ? strlen(rc) : -1; +} + +int +ip_address_to_sockaddr(const ip_address_t * ip_address, + struct sockaddr *sa, int family) +{ + struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *) sa; + struct sockaddr_in *tmp4 = (struct sockaddr_in *) sa; + + switch (family) + { + case AF_INET6: + tmp6->sin6_family = AF_INET6; + tmp6->sin6_port = DUMMY_PORT; + tmp6->sin6_scope_id = 0; + memcpy (&tmp6->sin6_addr, ip_address->buffer, IPV6_ADDR_LEN); + break; + case AF_INET: + tmp4->sin_family = AF_INET; + tmp4->sin_port = DUMMY_PORT; + memcpy (&tmp4->sin_addr, ip_address->buffer, IPV4_ADDR_LEN); + break; + default: + return -1; + } + + return 1; +} + +int +ip_address_cmp(const ip_address_t * ip1, const ip_address_t * ip2, int family) +{ + return memcmp(ip1, ip2, ip_address_len(ip1, family)); +} + +int +ip_address_empty(const ip_address_t * ip) +{ + return (memcmp(ip, &IP_ADDRESS_EMPTY, sizeof(IP_ADDRESS_EMPTY)) == 0); +} + + + +/* Prefix */ + +/* Parse IP Prefixes in presentation format (in bits, separated by a slash) */ +int +ip_prefix_pton (const char *ip_address_str, ip_prefix_t * ip_prefix) +{ + int pton_fd; + char *p; + char *eptr; + char *addr = strdup (ip_address_str); + + p = strchr (addr, '/'); + if (!p) + ip_prefix->len = 0; // until we get the ip address family + else { + ip_prefix->len = strtoul (p + 1, &eptr, 10); + *p = 0; + } + + ip_prefix->family = ip_address_get_family (addr); + + switch (ip_prefix->family) + { + case AF_INET6: + if (ip_prefix->len > IPV6_ADDR_LEN_BITS) + goto ERR; + pton_fd = inet_pton (AF_INET6, addr, &ip_prefix->address.buffer); + break; + case AF_INET: + if (ip_prefix->len > IPV4_ADDR_LEN_BITS) + goto ERR; + pton_fd = inet_pton (AF_INET, addr, &ip_prefix->address.buffer); + break; + default: + goto ERR; + } + + // 0 = not in presentation format + // < 0 = other error (use perror) + if (pton_fd <= 0) + goto ERR; + + return 1; +ERR: + free (addr); + return -1; +} + +int +ip_prefix_ntop (const ip_prefix_t * ip_prefix, char *dst, size_t size) +{ + char ip_s[MAXSZ_IP_ADDRESS]; + const char * s = inet_ntop (ip_prefix->family, ip_prefix->address.buffer, ip_s, MAXSZ_IP_ADDRESS); + if (!s) + return -1; + size_t n = snprintf(dst, size, "%s/%d", ip_s, ip_prefix->len); + + return (n > 0 ? 1 : -1); +} + +int +ip_prefix_len (const ip_prefix_t * prefix) +{ + return prefix->len; // ip_address_len(&prefix->address, prefix->family); +} + +bool +ip_prefix_empty (const ip_prefix_t * prefix) +{ + return prefix->len == 0; +} + +int ip_prefix_to_sockaddr(const ip_prefix_t * prefix, + struct sockaddr *sa) +{ + // XXX assert len == ip_address_len + return ip_address_to_sockaddr(&prefix->address, sa, prefix->family); +} + + +/* 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) +{ + char * cur = s; + int rc; + + /* Other address are currently not supported */ + if (!IS_VALID_FAMILY(family)) { + return -1; + } + + rc = snprintf(cur, s + size - cur, "inet%c://", + (family == AF_INET) ? '4' : '6'); + if (rc < 0) + return rc; + cur += rc; + if (size != 0 && cur >= s + size) + return cur - s; + + rc = ip_address_snprintf(cur, s + size - cur, ip_address, family); + if (rc < 0) + return rc; + cur += rc; + if (size != 0 && cur >= s + size) + return cur - s; + + rc = snprintf(cur, s + size - cur, ":"); + if (rc < 0) + return rc; + cur += rc; + if (size != 0 && cur >= s + size) + return cur - s; + + rc = snprintf(cur, s + size - cur, "%d", port); + if (rc < 0) + return rc; + cur += rc; + if (size != 0 && cur >= s + size) + return cur - s; + + return cur - s; +} -- cgit 1.2.3-korg