diff options
author | Luca Muscariello <muscariello@ieee.org> | 2022-08-04 16:06:34 +0200 |
---|---|---|
committer | Luca Muscariello <muscariello@ieee.org> | 2022-08-04 16:31:51 +0200 |
commit | 6d22a0db96aa7f8e3102ae44d00c09e36a2e9c57 (patch) | |
tree | 79546bbf09f6fbf74db7bc89117843f06ce937ea /lib | |
parent | 012843b1c0bc0838e69085ed83a79ec8b6f97360 (diff) |
feat: Due to the deep modifications related to names and packet format,
this task cover a large part of the codebase and involves several changes:
- the library provides a name data structure (hicn_name_t ), which is composed
of a name prefix (hicn_name_prefix_t) and a name suffix (hicn_name_suffix_t),
and it has been extended to provide all support functions required for name
manipulation, including common prefix computation, as required for the Longest
Prefix Match (LPM)in the forwarder, in addition to Exact Prefix Match (EPM).
- all code has been rewritten to use this data structure instead of having for
instance the forwarder define its own name class (used to be Name and NameBitVector)
the code has been refactored to minimize name allocations and copies, one remaining
aspect is the difference of name storage between PIT and CS entries (respectively
in the PIT entry, and in the message buffer), which causes the packet cache
index to be updated when a PIT entry is converted into a CS entry. By storing
the name in the PIT/CS entry everytime, we might save on this operation).
- hicn-light FIB has been rewritten : code has been refactored and should now be
shorter and documented; unit tests have been drafted but more would be required
to cover all cases and match the algorithms to add/remove nodes, as specified in the doc.
all protocol details and hICN header formats are now abstracted by the library
for the forwarder (and thus header.h and protocols/*.h have been removed from
public includes, and replaced by packet.h providing protocol agnostic packet
level functions, completely replacing the compat.h header that used to provide
similar functions.
- this works by exposing a opaque buffer to the application (a kind of socket buffer)
which is used by the lib to cache the packet format and offsets of the different
layers in the buffer and provider efficient operations (the packet format is
either defined for packet construction, or guessed at ingress, and this structure
is updated accordingly only once).
Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Change-Id: I31e321897f85f0267fe8ba4720363c180564492f
Diffstat (limited to 'lib')
63 files changed, 7350 insertions, 4698 deletions
diff --git a/lib/includes/CMakeLists.txt b/lib/includes/CMakeLists.txt index 392c2c94e..61af7eca8 100644 --- a/lib/includes/CMakeLists.txt +++ b/lib/includes/CMakeLists.txt @@ -24,29 +24,19 @@ set(LIBHICN_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/hicn/hicn.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/base.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/common.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/compat.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/error.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/face.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/header.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/mapme.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/name.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/packet.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/policy.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ops.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/strategy.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/validation.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/interest_manifest.h PARENT_SCOPE ) -set(LIBHICN_HEADER_FILES_PROTOCOL - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/ah.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/icmp.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/icmprd.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/ipv4.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/ipv6.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/tcp.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/udp.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/protocol/new.h +set(LIBHICN_HEADER_FILES_UTIL ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/array.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/bitmap.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/hash.h @@ -63,3 +53,6 @@ set(LIBHICN_HEADER_FILES_PROTOCOL ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/vector.h PARENT_SCOPE ) + +set_property(GLOBAL PROPERTY LIBHICN_HEADER_FILES_UTIL_PROPERTY "${LIBHICN_HEADER_FILES_UTIL}") + diff --git a/lib/includes/hicn/base.h b/lib/includes/hicn/base.h index b825619b7..0a6ac7321 100644 --- a/lib/includes/hicn/base.h +++ b/lib/includes/hicn/base.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -32,8 +32,16 @@ /* Default header fields */ #define HICN_DEFAULT_TTL 254 +#define SYMBOLIC_NAME_LEN 16 + +/* hICN attribute types */ + +/* Face id */ + typedef u32 hicn_faceid_t; -typedef u8 hicn_pathlabel_t; + +/* Lifetime */ + typedef u32 hicn_lifetime_t; #define HICN_MAX_LIFETIME_SCALED 0xFFFF @@ -56,6 +64,9 @@ typedef u32 hicn_lifetime_t; * currently used by an hypothetical signed MAP-Me update : * [IPPROTO_ICMPRD, IPPROTO_AH, IPPROTO_ICMP, IPPROTO_IPV6] */ + +#define HICN_FORMAT_LEN 4 + typedef union { /** protocol layers representation */ @@ -82,82 +93,166 @@ typedef union }; /** u32 representation */ u32 as_u32; -} hicn_type_t; + u8 as_u8[HICN_FORMAT_LEN]; +} hicn_packet_format_t; /* Common protocol layers */ /* Common protocol layers */ #ifndef _WIN32 -#define HICN_TYPE(x, y, z, t) \ - (hicn_type_t) \ +#define HICN_PACKET_FORMAT(x, y, z, t) \ + (hicn_packet_format_t) \ { \ { \ .l1 = x, .l2 = y, .l3 = z, .l4 = t \ } \ } #else -inline hicn_type_t -HICN_TYPE (int x, int y, int z, int t) +inline const hicn_packet_format_t +HICN_PACKET_FORMAT (int x, int y, int z, int t) { - hicn_type_t type; - type.l1 = x; - type.l2 = y; - type.l3 = z; - type.l4 = t; - return type; + hicn_packet_format_t format; + format.l1 = x; + format.l2 = y; + format.l3 = z; + format.l4 = t; + return format; } #endif -#define HICN_TYPE_IPV4_TCP \ - HICN_TYPE (IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE) -#define HICN_TYPE_IPV4_ICMP \ - HICN_TYPE (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE) -#define HICN_TYPE_IPV6_TCP \ - HICN_TYPE (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE) -#define HICN_TYPE_IPV6_ICMP \ - HICN_TYPE (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE, IPPROTO_NONE) -#define HICN_TYPE_NEW \ - HICN_TYPE (IPPROTO_ENCAP, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE) -#define HICN_TYPE_IPV4_UDP \ - HICN_TYPE (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE) -#define HICN_TYPE_IPV6_UDP \ - HICN_TYPE (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE) -#define HICN_TYPE_IPV4_TCP_AH \ - HICN_TYPE (IPPROTO_IP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE) -#define HICN_TYPE_IPV4_ICMP_AH \ - HICN_TYPE (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_AH, IPPROTO_NONE) -#define HICN_TYPE_IPV6_TCP_AH \ - HICN_TYPE (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE) -#define HICN_TYPE_IPV6_ICMP_AH \ - HICN_TYPE (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE) -#define HICN_TYPE_NEW_AH \ - HICN_TYPE (IPPROTO_ENCAP, IPPROTO_AH, IPPROTO_NONE, IPPROTO_NONE) -#define HICN_TYPE_IPV6_UDP_AH \ - HICN_TYPE (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH) -#define HICN_TYPE_IPV4_UDP_AH \ - HICN_TYPE (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH) -#define HICN_TYPE_NONE \ - HICN_TYPE (IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE) +extern const char *const _protocol_str[]; + +#define protocol_str(x) protocol_str[x] + +int hicn_packet_format_snprintf (char *s, size_t size, + hicn_packet_format_t format); + +#define MAXSZ_HICN_PACKET_FORMAT 4 * 4 + 3 // ICMP/ICMP/ICMP/ICMP + +#if !defined(__cplusplus) +#define constexpr const +#endif + +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_TCP = + HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_ICMP = + HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_TCP = + HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_ICMP = + HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE, + IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_NEW = + HICN_PACKET_FORMAT (IPPROTO_ENCAP, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_UDP = + HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_UDP = + HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_TCP_AH = + HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_ICMP_AH = + HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_ICMP, IPPROTO_AH, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_TCP_AH = + HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_ICMP_AH = + HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_NEW_AH = + HICN_PACKET_FORMAT (IPPROTO_ENCAP, IPPROTO_AH, IPPROTO_NONE, IPPROTO_NONE); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV6_UDP_AH = + HICN_PACKET_FORMAT (IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_IPV4_UDP_AH = + HICN_PACKET_FORMAT (IPPROTO_IP, IPPROTO_UDP, IPPROTO_ENCAP, IPPROTO_AH); +static constexpr hicn_packet_format_t HICN_PACKET_FORMAT_NONE = + HICN_PACKET_FORMAT (IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE); + +/** + * @brief Return the hICN format with an additional AH header + * @param [in] format - hICN packet format + * @return Updated hICN packet format + */ +static inline hicn_packet_format_t +hicn_get_ah_format (hicn_packet_format_t format) +{ + hicn_packet_format_t ret = format; + for (unsigned i = 0; i < HICN_FORMAT_LEN; i++) + { + switch (ret.as_u8[i]) + { + case IPPROTO_AH: + return ret; + case IPPROTO_NONE: + ret.as_u8[i] = IPPROTO_AH; + return ret; + default: + break; + } + } + return ret; +} + +/* + * MAX(IPV4_HDRLEN (20), IPV6_HDRLEN (40)) + * + MAX (TCP_HDRLEN (20), UDP_HDRLEN (8), ICMP_HDRLEN (8), NEW_HDRLEN (32)) + * + AH_HDRLEN + */ +#define HICN_HDRLEN_MAX 72 /** * @brief Check if type is none. * @return 1 if none, 0 otherwise */ static inline int -hicn_type_is_none (hicn_type_t type) +hicn_type_is_none (hicn_packet_format_t format) { - return (type.l1 == IPPROTO_NONE) && (type.l2 == IPPROTO_NONE) && - (type.l3 == IPPROTO_NONE) && (type.l4 == IPPROTO_NONE); + return (format.l1 == IPPROTO_NONE) && (format.l2 == IPPROTO_NONE) && + (format.l3 == IPPROTO_NONE) && (format.l4 == IPPROTO_NONE); } +#define _is_ipv4(format) (format.l1 == IPPROTO_IP) +#define _is_ipv6(format) (format.l1 == IPPROTO_IPV6) +#define _is_tcp(format) (format.l2 == IPPROTO_TCP) +#define _is_udp(format) (format.l2 == IPPROTO_UDP) +#define _is_icmp(format) \ + ((format.l2 == IPPROTO_ICMP) || (format.l2 == IPPROTO_ICMPV6)) +#define _is_cmpr(format) ((format & HFO_CMPR) >> 5) +#define _is_ah(format) \ + ((format.l1 == IPPROTO_AH) || (format.l2 == IPPROTO_AH) || \ + (format.l3 == IPPROTO_AH)) + +/* + * @brief hICN packet types + * + * probes are like normal interest & data but: + * - interests use BFD port as the destination + * - data use BFD port as the source + expiry time must be 0. + * if any of these conditions is not met, the packet is still matched as an + * interest or data packet. + * + */ + +#define foreach_packet_type \ + _ (UNDEFINED) \ + _ (INTEREST) \ + _ (DATA) \ + _ (WLDR_NOTIFICATION) \ + _ (MAPME) \ + _ (PROBE) \ + _ (COMMAND) \ + _ (N) + /** * @brief hICN Packet type */ typedef enum { - HICN_PACKET_TYPE_INTEREST, - HICN_PACKET_TYPE_DATA, - HICN_PACKET_N_TYPE, +#define _(x) HICN_PACKET_TYPE_##x, + foreach_packet_type +#undef _ } hicn_packet_type_t; +#undef foreach_type + +extern const char *_hicn_packet_type_str[]; + +#define hicn_packet_type_str(x) _hicn_packet_type_str[x] /** * @brief hICN Payload type @@ -172,60 +267,11 @@ typedef enum HPT_UNSPEC = 999 } hicn_payload_type_t; -/*************************************************************** - * Interest Manifest - ***************************************************************/ - -#define MAX_SUFFIXES_IN_MANIFEST 255 -#define WORD_WIDTH (sizeof (uint32_t) * 8) -#define BITMAP_SIZE ((MAX_SUFFIXES_IN_MANIFEST + 1) / WORD_WIDTH) - -typedef struct -{ - /* This can be 16 bits, but we use 32 bits for alignment */ - uint32_t n_suffixes; - - uint32_t request_bitmap[BITMAP_SIZE]; - - /* Followed by the list of prefixes to ask */ - /* ... */ -} interest_manifest_header_t; - -// Bitmap operations - -static inline void -set_bit (uint32_t *bitmap, int i) -{ - size_t offset = i / WORD_WIDTH; - size_t pos = i % WORD_WIDTH; - bitmap[offset] |= ((uint32_t) 1 << pos); -} - -static inline void -unset_bit (uint32_t *bitmap, int i) -{ - size_t offset = i / WORD_WIDTH; - size_t pos = i % WORD_WIDTH; - bitmap[offset] &= ~((uint32_t) 1 << pos); -} +/* Path label */ -static inline bool -is_bit_set (const uint32_t *bitmap, int i) -{ - size_t offset = i / WORD_WIDTH; - size_t pos = i % WORD_WIDTH; - return bitmap[offset] & ((uint32_t) 1 << pos); -} +typedef u8 hicn_path_label_t; -static inline void -bitmap_print (u32 *bitmap, size_t n_words) -{ - for (size_t word = 0; word < n_words; word++) - { - for (int bit = 31; bit >= 0; bit--) - (is_bit_set (&bitmap[word], bit)) ? printf ("1") : printf ("0"); - } -} +#define INVALID_PATH_LABEL 0 /** * @brief Path label computations @@ -237,28 +283,28 @@ bitmap_print (u32 *bitmap, size_t n_words) * NOTE: this computation is not (yet) part of the hICN specification. */ -#define HICN_PATH_LABEL_MASK 0x000000ff -#define HICN_PATH_LABEL_SIZE 8 +#define HICN_PATH_LABEL_MASK 0x000000ff +#define HICN_PATH_LABEL_SIZE_BITS sizeof (hicn_path_label_t) * 8 /** * @brief Path label update - * @param [in] current_label Current pathlabel + * @param [in] current_label Current path_label * @param [in] face_id The face identifier to combine into the path label - * @param [out] new_label Computed pathlabel + * @param [out] new_label Computed path_label * * This function updates the current_label based on the new face_id, and * returns */ static inline void -update_pathlabel (hicn_pathlabel_t current_label, hicn_faceid_t face_id, - hicn_pathlabel_t *new_label) +update_path_label (hicn_path_label_t current_label, hicn_faceid_t face_id, + hicn_path_label_t *new_label) { - hicn_pathlabel_t pl_face_id = - (hicn_pathlabel_t) (face_id & HICN_PATH_LABEL_MASK); + hicn_path_label_t pl_face_id = + (hicn_path_label_t) (face_id & HICN_PATH_LABEL_MASK); - *new_label = - ((current_label << 1) | (current_label >> (HICN_PATH_LABEL_SIZE - 1))) ^ - pl_face_id; + *new_label = ((current_label << 1) | + (current_label >> (HICN_PATH_LABEL_SIZE_BITS - 1))) ^ + pl_face_id; } /*************************************************************** diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h index 1998099db..a84124617 100644 --- a/lib/includes/hicn/common.h +++ b/lib/includes/hicn/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -36,25 +36,11 @@ #include <stdint.h> #include <assert.h> -/* Concise type definitions */ +#include <hicn/util/types.h> -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -/* - * Code annotations - * - * NOTE: these are defined by default in VPP. - */ - -#ifndef HICN_VPP_PLUGIN - -#define PREDICT_FALSE(x) (x) -#define PREDICT_TRUE(x) (x) -#define STRUCT_SIZE_OF(type, member) sizeof (((type *) 0)->member) -#define ASSERT +#define HICN_EXPECT_FALSE(x) __builtin_expect ((x), 1) +#define HICN_EXPECT_TRUE(x) __builtin_expect ((x), 0) +#define HICN_UNUSED(x) x __attribute__ ((unused)) #ifndef NDEBUG #define _ASSERT(x) assert (x) @@ -62,36 +48,6 @@ typedef uint8_t u8; #define _ASSERT(x) ((void) (x)) #endif -#define STATIC_ASSERT(x) - -/* Architecture-dependent uword size */ -#if INTPTR_MAX == INT64_MAX -#define log2_uword_bits 6 -#elif INTPTR_MAX == INT32_MAX -#define log2_uword_bits 5 -#else -#error "Impossible to detect architecture" -#endif - -#define uword_bits (1 << log2_uword_bits) - -/* Word types. */ -#if uword_bits == 64 -/* 64 bit word machines. */ -typedef u64 uword; -#else -/* 32 bit word machines. */ -typedef u32 uword; -#endif - -typedef uword ip_csum_t; - -#else - -#include <vppinfra/clib.h> - -#endif /* ! HICN_VPP_PLUGIN */ - /* * Windows compilers do not support named initilizers when .h files are * included inside C++ files. For readability, we either use the following @@ -178,11 +134,11 @@ int get_addr_family (const char *ip_address); */ static inline u16 -ip_csum_fold (ip_csum_t c) +ip_csum_fold (hicn_ip_csum_t c) { /* Reduce to 16 bits. */ #if uword_bits == 64 - c = (c & (ip_csum_t) 0xffffffff) + (c >> (ip_csum_t) 32); + c = (c & (hicn_ip_csum_t) 0xffffffff) + (c >> (hicn_ip_csum_t) 32); c = (c & 0xffff) + (c >> 16); #endif @@ -192,18 +148,18 @@ ip_csum_fold (ip_csum_t c) return (u16) c; } -static inline ip_csum_t -ip_csum_with_carry (ip_csum_t sum, ip_csum_t x) +static inline hicn_ip_csum_t +ip_csum_with_carry (hicn_ip_csum_t sum, hicn_ip_csum_t x) { - ip_csum_t t = sum + x; + hicn_ip_csum_t t = sum + x; return t + (t < x); } /* Update checksum changing field at even byte offset from x -> 0. */ -static inline ip_csum_t -ip_csum_add_even (ip_csum_t c, ip_csum_t x) +static inline hicn_ip_csum_t +ip_csum_add_even (hicn_ip_csum_t c, hicn_ip_csum_t x) { - ip_csum_t d; + hicn_ip_csum_t d; d = c - x; @@ -214,8 +170,8 @@ ip_csum_add_even (ip_csum_t c, ip_csum_t x) } /* Update checksum changing field at even byte offset from 0 -> x. */ -static inline ip_csum_t -ip_csum_sub_even (ip_csum_t c, ip_csum_t x) +static inline hicn_ip_csum_t +ip_csum_sub_even (hicn_ip_csum_t c, hicn_ip_csum_t x) { return ip_csum_with_carry (c, x); } @@ -265,8 +221,19 @@ csum (const void *addr, size_t size, u16 init) * Query IP version from packet (either 4 or 6) * (version is located as same offsets in both protocol headers) */ -#define HICN_IP_VERSION(packet) \ - ((hicn_header_t *) packet)->protocol.ipv4.version +typedef struct +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + u8 dummy : 4; + u8 version : 4; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8 version : 4; + u8 dummy : 4; +#else +#error "Unsupported endianness" +#endif +} ip_version_t; +#define HICN_IP_VERSION(packet) ((ip_version_t *) packet)->version #ifndef ntohll static inline uint64_t @@ -296,9 +263,9 @@ htonll (uint64_t input) } #endif -#define round_pow2(x, pow2) (((x) + (pow2) -1) & ~((pow2) -1)) +#define hicn_round_pow2(x, pow2) (((x) + (pow2) -1) & ~((pow2) -1)) -#define _SIZEOF_ALIGNED(x, size) round_pow2 (sizeof (x), size) +#define _SIZEOF_ALIGNED(x, size) hicn_round_pow2 (sizeof (x), size) #define SIZEOF_ALIGNED(x) _SIZEOF_ALIGNED (x, sizeof (void *)) /* Definitions for builtins unavailable on MSVC */ @@ -336,6 +303,7 @@ uint32_t __inline __builtin_clzl2 (uint64_t value) #endif #define next_pow2(x) (x <= 1 ? 1 : 1ul << (64 - __builtin_clzl (x - 1))) +#define _unused(x) ((void) (x)) #endif /* HICN_COMMON_H */ diff --git a/lib/includes/hicn/compat.h b/lib/includes/hicn/compat.h deleted file mode 100644 index 98c035b57..000000000 --- a/lib/includes/hicn/compat.h +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file compat.h - * @brief Implementation of the compatibility layer. - * - * The structure of the core API has evolved to support operations of a variety - * of packet formats in addition to IPv4/TCP and IPv6/TCP, namely with the use - * of ICMP for signalization and AH headers for integrity. The new API format - * has been designed to scale better with the multiplicity of packet formats, - * and provide a unified interface on top. We maintain an interface for the - * former API in this file, which mainly acts as a wrapper on top of new calls. - */ -#ifndef HICN_COMPAT_H -#define HICN_COMPAT_H - -#include "common.h" -#include "header.h" -#include "name.h" - -/* HICN format options */ -#define HFO_INET 1 << 0 -#define HFO_INET6 1 << 1 -#define HFO_TCP 1 << 2 -#define HFO_UDP 1 << 3 -#define HFO_ICMP 1 << 4 -#define HFO_CMPR 1 << 5 -#define HFO_AH 1 << 6 - -#define _is_ipv4(format) ((format & HFO_INET)) -#define _is_ipv6(format) ((format & HFO_INET6) >> 1) -#define _is_tcp(format) ((format & HFO_TCP) >> 2) -#define _is_udp(format) ((format & HFO_UDP) >> 3) -#define _is_icmp(format) ((format & HFO_ICMP) >> 4) -#define _is_cmpr(format) ((format & HFO_CMPR) >> 5) -#define _is_ah(format) ((format & HFO_AH) >> 6) - -typedef enum -{ - HF_UNSPEC = 0, - HF_INET_TCP = HFO_INET | HFO_TCP, - HF_INET6_TCP = HFO_INET6 | HFO_TCP, - HF_INET_ICMP = HFO_INET | HFO_ICMP, - HF_INET6_ICMP = HFO_INET6 | HFO_ICMP, - HF_NEW = HFO_CMPR, - HF_INET_UDP = HFO_INET | HFO_UDP | HFO_CMPR, - HF_INET6_UDP = HFO_INET6 | HFO_UDP | HFO_CMPR, - HF_INET_TCP_AH = HFO_INET | HFO_TCP | HFO_AH, - HF_INET6_TCP_AH = HFO_INET6 | HFO_TCP | HFO_AH, - HF_INET_ICMP_AH = HFO_INET | HFO_ICMP | HFO_AH, - HF_INET6_ICMP_AH = HFO_INET6 | HFO_ICMP | HFO_AH, - HF_NEW_AH = HFO_CMPR | HFO_AH, - HF_INET_UDP_AH = HFO_INET | HFO_UDP | HFO_CMPR | HFO_AH, - HF_INET6_UDP_AH = HFO_INET6 | HFO_UDP | HFO_CMPR | HFO_AH, -} hicn_format_t; - -/** - * @brief Add AH header to current format. E.g. if format is IP + TCP, this - * will change it to IP = TCP + AH - * - * @param [in] format - The input format - * @return The format with the AH bit set to 1 - */ -static inline hicn_format_t -hicn_get_ah_format (hicn_format_t format) -{ - return (hicn_format_t) (format | HFO_AH); -} - -/** - * Minimum required header length to determine the type and length of a - * supposed hICN packet. This should be equal to the maximum value over all - * possible hICN packet formats, and less than the minimum possible IP packet - * size. - */ -#define HICN_V6_MIN_HDR_LEN 6 /* bytes */ -#define HICN_V4_MIN_HDR_LEN 4 /* bytes */ - -// #define HICN_MIN_HDR_LEN ((HICN_V6_MIN_HDR_LEN > HICN_V4_MIN_HDR_LEN) ? -// HICN_V6_MIN_HDR_LEN : HICN_V4_MIN_HDR_LEN) -#define HICN_MIN_HDR_LEN HICN_V6_MIN_HDR_LEN - -hicn_type_t hicn_header_to_type (const hicn_header_t *h); - -/** - * @brief Parse packet headers and return hICN format - * @param [in] format - hICN Format - * @param [in, out] packet - Buffer containing the hICN header to be - * initialized - * @return hICN error code - */ -int hicn_packet_init_header (hicn_format_t format, hicn_header_t *packet); - -/** - * @brief Parse packet headers and return hICN format - * @param [in] h - hICN header - * @param [out] format - hICN format - * @return hICN error code - */ -int hicn_packet_get_format (const hicn_header_t *packet, - hicn_format_t *format); - -/** - * @brief Update checksums in packet headers - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @return hICN error code - */ -int hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t *packet); - -/** - * @brief compute the checksum of the packet header, adding init_sum to the - * final value - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @param [in] init_sum - value to add to the final checksum - * @return hICN error code - */ -int hicn_packet_compute_header_checksum (hicn_format_t format, - hicn_header_t *packet, u16 init_sum); - -/** - * @brief Verify checksums in packet headers - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @return hICN error code - */ -int hicn_packet_check_integrity_no_payload (hicn_format_t format, - hicn_header_t *packet, - u16 init_sum); - -// this is not accounted here -/** - * @brief Return total length of hicn headers (but signature payload) - * @param [in] format - hICN format - * @param [out] header_length - Total length of headers - * @return hICN error code - */ -int hicn_packet_get_header_length_from_format (hicn_format_t format, - size_t *header_length); - -/** - * @brief Return total length of hicn headers (before payload) - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] header_length - Total length of headers - * @return hICN error code - */ -int hicn_packet_get_header_length (hicn_format_t format, - const hicn_header_t *packet, - size_t *header_length); - -/** - * @brief Return payload length - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] payload_length - payload length - * @return hICN error code - */ -int hicn_packet_get_payload_length (hicn_format_t format, - const hicn_header_t *packet, - size_t *payload_length); - -/** - * @brief Sets payload length - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @param [in] payload_length - payload length - * @return hICN error code - */ -int hicn_packet_set_payload_length (hicn_format_t format, - hicn_header_t *packet, - const size_t payload_length); - -/** - * @brief Compare two hICN packets - * @param [in] packet_1 - First packet - * @param [in] packet_2 - Second packet - * @return 0 if both packets are considered equal, any other value otherwise. - */ -int hicn_packet_compare (const hicn_header_t *packet1, - const hicn_header_t *packet2); - -/** - * @brief Retrieve the name of an interest/data packet - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] name - name holding the result - * @param [in] is_interest - Flag to determine whether it is an interest (1) or - * data packet (0) - * @return hICN error code - */ -int hicn_packet_get_name (hicn_format_t format, const hicn_header_t *packet, - hicn_name_t *name, u8 is_interest); - -/** - * @brief Sets the name of an interest/data packet - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @param [in] name - name to set into packet - * @param [in] is_interest - Flag to determine whether it is an interest (1) or - * data packet (0) - * @return hICN error code - */ -int hicn_packet_set_name (hicn_format_t format, hicn_header_t *packet, - const hicn_name_t *name, u8 is_interest); - -/** - * @brief Sets the payload of a packet - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @param [in] payload - payload to set - * @param [in] payload_length - size of the payload to set - * @return hICN error code - * - * NOTE: - * - The buffer holding payload is assumed sufficiently large - * - This function updates header fields with the new length, but no checksum. - */ -int hicn_packet_set_payload (hicn_format_t format, hicn_header_t *packet, - const u8 *payload, u16 payload_length); - -/** - * @brief Retrieves the payload of a packet - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] payload - pointer to buffer for storing the result - * @param [out] payload_length - size of the retreived payload - * @param [in] hard_copy - Flag : if true (eg. 1), a copy of the payload is - * made into the payload buffer, otherwise (0) the pointer is changed to point - * to the payload offset in the packet. - * @return hICN error code - * - * NOTE: - * - The buffer holding payload is assumed sufficiently large - */ -int hicn_packet_get_payload (hicn_format_t format, const hicn_header_t *packet, - u8 **payload, size_t *payload_size, - bool hard_copy); - -/** - * @brief Retrieve the locator of an interest / data packet - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] ip_address - retrieved locator - * @param [in] is_interest - Flag to determine whether it is an interest (1) or - * data packet (0) - * @return hICN error code - */ -int hicn_packet_get_locator (hicn_format_t format, const hicn_header_t *packet, - ip_address_t *prefix, bool is_interest); - -/** - * @brief Sets the locator of an interest / data packet - * @param [in] format - hICN format - * @param [in,out] packet - packet header - * @param [out] ip_address - retrieved locator - * @param [in] is_interest - Flag to determine whether it is an interest (1) or - * data packet (0) - * @return hICN error code - */ -int hicn_packet_set_locator (hicn_format_t format, hicn_header_t *packet, - const ip_address_t *prefix, bool is_interest); - -/** - * @brief Retrieves the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] bytes - Retrieved signature size - * @return hICN error code - */ -int hicn_packet_get_signature_size (hicn_format_t format, - const hicn_header_t *packet, - size_t *bytes); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [in] bytes - Retrieved signature size - * @return hICN error code - */ -int hicn_packet_set_signature_size (hicn_format_t format, - hicn_header_t *packet, size_t bytes); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [in] signature_timestamp - Signature timestamp to set - * @return hICN error code - */ -int hicn_packet_set_signature_timestamp (hicn_format_t format, - hicn_header_t *h, - uint64_t signature_timestamp); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] signature_timestamp - Retrieved signature timestamp - * @return hICN error code - */ -int hicn_packet_get_signature_timestamp (hicn_format_t format, - const hicn_header_t *h, - uint64_t *signature_timestamp); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [in] validation_algorithm - Validation algorithm to set - * @return hICN error code - */ -int hicn_packet_set_validation_algorithm (hicn_format_t format, - hicn_header_t *h, - uint8_t validation_algorithm); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] validation_algorithm - Retrieved validation algorithm - * @return hICN error code - */ -int hicn_packet_get_validation_algorithm (hicn_format_t format, - const hicn_header_t *h, - uint8_t *validation_algorithm); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [in] key_id - Key id to set - * @return hICN error code - */ -int hicn_packet_set_key_id (hicn_format_t format, hicn_header_t *h, - uint8_t *key_id); - -/** - * @brief Sets the signature size - * @param [in] format - hICN format - * @param [in] packet - packet header - * @param [out] key_id - Retrieved key id - * @return hICN error code - */ -int hicn_packet_get_key_id (hicn_format_t format, hicn_header_t *h, - uint8_t **key_id, uint8_t *key_id_length); - -/** - * @brief Retrieves the packet hop limit - * @param [in] packet - packet header - * @param [out] hops - Retrieved hop limit - * @return hICN error code - */ -int hicn_packet_get_hoplimit (const hicn_header_t *packet, u8 *hops); - -/** - * @brief Sets the packet hop limit - * @param [in] packet - packet header - * @param [in] hops - Hop limit to set - * @return hICN error code - */ -int hicn_packet_set_hoplimit (hicn_header_t *packet, u8 hops); - -/** - * @brief Check if this packet is interest - * - * @param format - hICN format - * @param packet - Packet header - * @return hICN error code - */ -int hicn_packet_is_interest (hicn_format_t format, const hicn_header_t *h, - int *ret); - -/** - * @brief Mark this packet as interest - * - * @param format - hICN format - * @param packet - Packet header - * @return hICN error code - */ -int hicn_packet_set_interest (hicn_format_t format, hicn_header_t *packet); - -/** - * @brief Mark this packet as data - * - * @param format - hICN format - * @param packet - Packet header - * @return hICN error code - */ -int hicn_packet_set_data (hicn_format_t format, hicn_header_t *h); - -int hicn_packet_copy_header (hicn_format_t format, const hicn_header_t *packet, - hicn_header_t *destination, bool copy_ah); - -int hicn_packet_get_lifetime (hicn_format_t format, - const hicn_header_t *packet, u32 *lifetime); -int hicn_packet_set_lifetime (hicn_format_t format, hicn_header_t *packet, - u32 lifetime); -int hicn_packet_get_reserved_bits (const hicn_header_t *packet, - u8 *reserved_bits); -int hicn_packet_set_reserved_bits (hicn_header_t *packet, - const u8 reserved_bits); -int hicn_packet_get_payload_type (hicn_format_t format, - const hicn_header_t *packet, - hicn_payload_type_t *payload_type); -int hicn_packet_set_payload_type (hicn_format_t format, hicn_header_t *packet, - const hicn_payload_type_t payload_type); - -int hicn_packet_set_syn (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_reset_syn (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_test_syn (hicn_format_t format, const hicn_header_t *packet, - bool *flag); -int hicn_packet_set_ack (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_reset_ack (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_test_ack (hicn_format_t format, const hicn_header_t *packet, - bool *flag); -int hicn_packet_set_rst (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_reset_rst (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_test_rst (hicn_format_t format, const hicn_header_t *packet, - bool *flag); -int hicn_packet_set_fin (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_reset_fin (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_test_fin (hicn_format_t format, const hicn_header_t *packet, - bool *flag); -int hicn_packet_set_ece (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_reset_ece (hicn_format_t format, hicn_header_t *packet); -int hicn_packet_test_ece (hicn_format_t format, const hicn_header_t *packet, - bool *flag); - -int hicn_packet_set_src_port (hicn_format_t format, hicn_header_t *packet, - u16 src_port); -int hicn_packet_get_src_port (hicn_format_t format, - const hicn_header_t *packet, u16 *src_port); -int hicn_packet_set_dst_port (hicn_format_t format, hicn_header_t *packet, - u16 dst_port); -int hicn_packet_get_dst_port (hicn_format_t format, - const hicn_header_t *packet, u16 *dst_port); -int hicn_packet_get_signature (hicn_format_t format, hicn_header_t *packet, - uint8_t **sign_buf); - -/* Interest */ -int hicn_interest_get_name (hicn_format_t format, - const hicn_header_t *interest, hicn_name_t *name); -int hicn_interest_set_name (hicn_format_t format, hicn_header_t *interest, - const hicn_name_t *name); -int hicn_interest_get_locator (hicn_format_t format, - const hicn_header_t *interest, - ip_address_t *prefix); -int hicn_interest_set_locator (hicn_format_t format, hicn_header_t *interest, - const ip_address_t *prefix); -int hicn_interest_compare (const hicn_header_t *interest_1, - const hicn_header_t *interest_2); -int hicn_interest_set_lifetime (hicn_header_t *interest, u32 lifetime); -int hicn_interest_get_lifetime (const hicn_header_t *interest, u32 *lifetime); -int hicn_interest_get_header_length (hicn_format_t format, - const hicn_header_t *interest, - size_t *header_length); -int hicn_interest_get_payload_length (hicn_format_t format, - const hicn_header_t *interest, - size_t *payload_length); -int hicn_interest_set_payload (hicn_format_t format, hicn_header_t *interest, - const u8 *payload, size_t payload_length); -int hicn_interest_get_payload (hicn_format_t format, - const hicn_header_t *interest, u8 **payload, - size_t *payload_size, bool hard_copy); -int hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t *packet); - -/* Data */ - -int hicn_data_get_name (hicn_format_t format, const hicn_header_t *data, - hicn_name_t *name); -int hicn_data_set_name (hicn_format_t format, hicn_header_t *data, - const hicn_name_t *name); -int hicn_data_get_locator (hicn_format_t format, const hicn_header_t *data, - ip_address_t *prefix); -int hicn_data_set_locator (hicn_format_t format, hicn_header_t *data, - const ip_address_t *prefix); -int hicn_data_compare (const hicn_header_t *data_1, - const hicn_header_t *data_2); -int hicn_data_get_expiry_time (const hicn_header_t *data, u32 *expiry_time); -int hicn_data_set_expiry_time (hicn_header_t *data, u32 expiry_time); -int hicn_data_get_header_length (hicn_format_t format, hicn_header_t *data, - size_t *header_length); -int hicn_data_get_payload_length (hicn_format_t format, - const hicn_header_t *data, - size_t *payload_length); -int hicn_data_get_path_label (const hicn_header_t *data, u32 *path_label); -int hicn_data_set_path_label (hicn_header_t *data, u32 path_label); -int hicn_data_get_payload (hicn_format_t format, const hicn_header_t *data, - u8 **payload, size_t *payload_size, bool hard_copy); -int hicn_data_set_payload (hicn_format_t format, hicn_header_t *data, - const u8 *payload, size_t payload_length); -int hicn_data_get_payload_type (const hicn_header_t *data, - hicn_payload_type_t *payload_type); -int hicn_data_set_payload_type (hicn_header_t *data, - hicn_payload_type_t payload_type); -int hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t *packet); -int hicn_data_is_last (hicn_format_t format, hicn_header_t *h, int *is_last); -int hicn_data_set_last (hicn_format_t format, hicn_header_t *h); - -int hicn_packet_get_signature_padding (hicn_format_t format, - const hicn_header_t *h, size_t *bytes); -int hicn_packet_set_signature_padding (hicn_format_t format, hicn_header_t *h, - size_t bytes); - -#endif /* HICN_COMPAT_H */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/lib/includes/hicn/error.h b/lib/includes/hicn/error.h index d769ef693..9926c9cd8 100644 --- a/lib/includes/hicn/error.h +++ b/lib/includes/hicn/error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -47,6 +47,8 @@ typedef enum extern const char *HICN_LIB_ERROR_STRING[]; +#define HICN_LIB_IS_ERROR(rc) (rc < 0) + #define hicn_strerror(errno) (char *) (HICN_LIB_ERROR_STRING[-errno]) #endif /* HICN_ERROR_H */ diff --git a/lib/includes/hicn/face.h b/lib/includes/hicn/face.h index 31906afab..fbdacec5f 100644 --- a/lib/includes/hicn/face.h +++ b/lib/includes/hicn/face.h @@ -37,6 +37,7 @@ /* Netdevice type */ #include <net/if.h> // IFNAMSIZ +#include "base.h" #define foreach_netdevice_type \ _ (UNDEFINED) \ @@ -58,10 +59,17 @@ typedef enum #undef _ } netdevice_type_t; +typedef uint32_t netdevice_flags_t; +#define NETDEVICE_FLAGS_EMPTY 0 +#define netdevice_flags_clear(F) (F = 0) +#define netdevice_flags_add(F, T) ((F) |= 1 << (T)) +#define netdevice_flags_remove(F, T) ((F) &= ~(1 << (T))) +#define netdevice_flags_has(F, T) ((F) & (1 << (T))) + extern const char *_netdevice_type_str[]; #define netdevice_type_str(x) _netdevice_type_str[x] -#define NETDEVICE_INVALID_INDEX ~0 +#define INVALID_NETDEVICE_ID ~0 /* Netdevice */ @@ -97,6 +105,7 @@ int netdevice_set_name (netdevice_t *netdevice, const char *name); int netdevice_update_index (netdevice_t *netdevice); int netdevice_update_name (netdevice_t *netdevice); int netdevice_cmp (const netdevice_t *nd1, const netdevice_t *nd2); +bool netdevice_is_empty (const netdevice_t *netdevice); #define NETDEVICE_UNDEFINED_INDEX 0 @@ -175,9 +184,12 @@ face_type_t face_type_from_str (const char *str); /* Face */ typedef u32 face_id_t; +#define INVALID_FACE_ID ~0 typedef struct { + face_id_t id; + char name[SYMBOLIC_NAME_LEN]; face_type_t type; face_state_t admin_state; face_state_t state; @@ -191,16 +203,16 @@ typedef struct */ netdevice_t netdevice; int family; /* To access family independently of face type */ - ip_address_t local_addr; - ip_address_t remote_addr; + hicn_ip_address_t local_addr; + hicn_ip_address_t remote_addr; u16 local_port; u16 remote_port; } face_t; int face_initialize (face_t *face); int face_initialize_udp (face_t *face, const char *interface_name, - const ip_address_t *local_addr, u16 local_port, - const ip_address_t *remote_addr, u16 remote_port, + const hicn_ip_address_t *local_addr, u16 local_port, + const hicn_ip_address_t *remote_addr, u16 remote_port, int family); int face_initialize_udp_sa (face_t *face, const char *interface_name, const struct sockaddr *local_addr, @@ -208,8 +220,8 @@ int face_initialize_udp_sa (face_t *face, const char *interface_name, face_t *face_create (); face_t *face_create_udp (const char *interface_name, - const ip_address_t *local_addr, u16 local_port, - const ip_address_t *remote_addr, u16 remote_port, + const hicn_ip_address_t *local_addr, u16 local_port, + const hicn_ip_address_t *remote_addr, u16 remote_port, int family); face_t *face_create_udp_sa (const char *interface_name, const struct sockaddr *local_addr, diff --git a/lib/includes/hicn/header.h b/lib/includes/hicn/header.h deleted file mode 100644 index 208e35d68..000000000 --- a/lib/includes/hicn/header.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file header.h - * @brief hICN header data structures. - * - * NOTE: These structures are used as convenient facade for accessing - * the encapsulated headers. They are not written taking compiler padding - * into account, then a sizeof() on these struct could not give the expected - * result. For accessing the size of the hicn headers use the macros at the end - * of this file. - */ - -#ifndef HICN_HEADER_H -#define HICN_HEADER_H - -#include "common.h" -#include "protocol.h" - -typedef struct -{ - _ipv6_header_t ip; - union - { - _tcp_header_t tcp; - struct - { - _udp_header_t udp; - _new_header_t newhdr; - }; - _icmp_header_t icmp; - _icmp_wldr_header_t wldr; - }; -} hicn_v6_hdr_t; - -typedef struct -{ - _ipv6_header_t ip; - union - { - struct - { - _tcp_header_t tcp; - _ah_header_t ah; - }; - struct - { - _udp_header_t udp; - _new_header_t newhdr; - _ah_header_t udp_ah; - }; - struct - { - _icmp_header_t icmp; - _ah_header_t icmp_ah; - }; - }; -} hicn_v6ah_hdr_t; - -// For ipv4 we need to use packed structs as fields may be aligned to 64 bits -// (So for instance tcp header may start at byte #24 instead of byte 20) -typedef PACKED (struct { - _ipv4_header_t ip; - union - { - _tcp_header_t tcp; - struct - { - _udp_header_t udp; - _new_header_t newhdr; - }; - _icmp_header_t icmp; - _icmp_wldr_header_t wldr; - }; -}) hicn_v4_hdr_t; - -typedef PACKED (struct { - _ipv4_header_t ip; - union - { - struct - { - _tcp_header_t tcp; - _ah_header_t ah; - }; - struct - { - _udp_header_t udp; - _new_header_t newhdr; - _ah_header_t udp_ah; - }; - struct - { - _icmp_header_t icmp; - _ah_header_t icmp_ah; - }; - }; -}) hicn_v4ah_hdr_t; - -typedef union -{ - /* To deprecate as redundant with hicn_type_t */ - hicn_v6_hdr_t v6; - hicn_v6ah_hdr_t v6ah; - hicn_v4_hdr_t v4; - hicn_v4ah_hdr_t v4ah; - - hicn_protocol_t protocol; -} hicn_header_t; - -#define HICN_V6_TCP_HDRLEN (IPV6_HDRLEN + TCP_HDRLEN) -#define HICN_V6_ICMP_HDRLEN (IPV6_HDRLEN + ICMP_HDRLEN) -#define HICN_V6_WLDR_HDRLEN (IPV6_HDRLEN + ICMPWLDR_HDRLEN) - -#define HICN_V6_TCP_AH_HDRLEN (HICN_V6_TCP_HDRLEN + AH_HDRLEN) -#define HICN_V6_ICMP_AH_HDRLEN (HICN_V6_ICMP_HDRLEN + AH_HDRLEN) - -#define HICN_V4_TCP_HDRLEN (IPV4_HDRLEN + TCP_HDRLEN) -#define HICN_V4_ICMP_HDRLEN (IPV4_HDRLEN + ICMP_HDRLEN) -#define HICN_V4_WLDR_HDRLEN (IPV4_HDRLEN + ICMPWLDR_HDRLEN) - -#define HICN_V4_TCP_AH_HDRLEN (HICN_V4_TCP_HDRLEN + AH_HDRLEN) -#define HICN_V4_ICMP_AH_HDRLEN (HICN_V4_ICMP_HDRLEN + AH_HDRLEN) - -#define HICN_DEFAULT_PORT 9695 - -#endif /* HICN_HEADER_H */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/lib/includes/hicn/hicn.h b/lib/includes/hicn/hicn.h index 4a5b4dd56..5e67d83a0 100644 --- a/lib/includes/hicn/hicn.h +++ b/lib/includes/hicn/hicn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -29,6 +29,14 @@ * Recovery (WLDR) [2], Anchorless Mobility Management (hICN-AMM) [3], * including MAP-Me producer mobility mechanisms [4]. * + * Other hICN constructs such as faces, policies and stategies are not included + * in this header, but available separately in : + * - hicn/face.h + * - hicn/policy.h + * - hicn/strategy.h + * + * REFERENCES + * * [1] Hybrid Information-Centric Networking * L. Muscariello, G. Carofiglio, J. Augé, M. Papalini * IETF draft (intarea) @ @@ -52,22 +60,21 @@ #ifndef HICN__H #define HICN__H -#ifdef HICN_VPP_PLUGIN +/* Base data structures */ +#include <hicn/base.h> -#include <hicn/header.h> +/* Names */ #include <hicn/name.h> -#include <hicn/ops.h> -#include <hicn/mapme.h> -#else +/* Packet operations */ +#include <hicn/packet.h> -#include <hicn/error.h> -#include <hicn/header.h> -#include <hicn/name.h> -#include <hicn/ops.h> +/* MAP-Me : mobility management operations */ #include <hicn/mapme.h> -#include <hicn/compat.h> +/* Error management */ +#ifndef HICN_VPP_PLUGIN +#include <hicn/error.h> #endif #endif /* HICN__H */ diff --git a/lib/includes/hicn/interest_manifest.h b/lib/includes/hicn/interest_manifest.h new file mode 100644 index 000000000..03f54d6d5 --- /dev/null +++ b/lib/includes/hicn/interest_manifest.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HICNLIGHT_INTEREST_MANIFEST_H +#define HICNLIGHT_INTEREST_MANIFEST_H + +#include <string.h> +#include <stdbool.h> + +#include <hicn/util/bitmap.h> +#include <hicn/base.h> + +typedef enum +{ + INT_MANIFEST_SPLIT_STRATEGY_NONE, + INT_MANIFEST_SPLIT_STRATEGY_MAX_N_SUFFIXES, + INT_MANIFEST_SPLIT_N_STRATEGIES, +} int_manifest_split_strategy_t; + +#define MAX_SUFFIXES_IN_MANIFEST 256 + +#define DEFAULT_DISAGGREGATION_STRATEGY \ + INT_MANIFEST_SPLIT_STRATEGY_MAX_N_SUFFIXES +#define DEFAULT_N_SUFFIXES_PER_SPLIT MAX_SUFFIXES_IN_MANIFEST + +#define BITMAP_SIZE (MAX_SUFFIXES_IN_MANIFEST / WORD_WIDTH) + +typedef struct +{ + /* This can be 16 bits, but we use 32 bits for alignment */ + uint32_t n_suffixes; + + /* Align to 64 bits */ + uint32_t padding; + + hicn_uword request_bitmap[BITMAP_SIZE]; + + /* Followed by the list of prefixes to ask */ + /* ... */ +} interest_manifest_header_t; + +static_assert (sizeof (interest_manifest_header_t) == 32 + 4 + 4, + "interest_manifest_header_t size must be 40 bytes"); + +static inline bool +interest_manifest_is_valid (interest_manifest_header_t *int_manifest_header, + size_t payload_length) +{ + if (int_manifest_header->n_suffixes == 0 || + int_manifest_header->n_suffixes > MAX_SUFFIXES_IN_MANIFEST) + { + return false; + } + + hicn_uword empty_bitmap[BITMAP_SIZE] = { 0 }; + if (memcmp (empty_bitmap, int_manifest_header->request_bitmap, + sizeof (empty_bitmap)) == 0) + { + return false; + } + + if (payload_length - sizeof (interest_manifest_header_t) != + int_manifest_header->n_suffixes * sizeof (u32)) + { + return false; + } + + return true; +} + +static inline size_t +interest_manifest_update_bitmap (const hicn_uword *initial_bitmap, + hicn_uword *bitmap_to_update, size_t start, + size_t n, size_t max_suffixes) +{ + size_t i = start, n_ones = 0; + while (i < n) + { + if (bitmap_is_set_no_check (initial_bitmap, i)) + { + bitmap_set_no_check (bitmap_to_update, i); + n_ones++; + } + i++; + + if (n_ones == max_suffixes) + break; + } + + return i; +} + +#endif /* HICNLIGHT_INTEREST_MANIFEST_H */ diff --git a/lib/includes/hicn/mapme.h b/lib/includes/hicn/mapme.h index 63a5cd77e..b452a5dde 100644 --- a/lib/includes/hicn/mapme.h +++ b/lib/includes/hicn/mapme.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -23,9 +23,9 @@ #include <stdint.h> // u32 #include <stdbool.h> +#include <hicn/name.h> + #include "common.h" -#include "protocol.h" -#include "ops.h" /** * @brief MAP-Me configuration options @@ -114,51 +114,11 @@ int hicn_mapme_parse_packet (const u8 *packet, hicn_prefix_t *prefix, /* Default TTL */ #define HICN_MAPME_TTL 255 // typical for redirect (ref?) -/* - * The length of the MAPME4 header struct must be 120 bytes. - */ -#define EXPECTED_MAPME_V4_HDRLEN 120 - -/** @brief MAP-Me packet header for IPv4 */ -typedef struct -{ - _ipv4_header_t ip; - _icmprd4_header_t icmp_rd; - seq_t seq; - u8 len; - u8 _pad[3]; -} hicn_mapme_v4_header_t; +/* Should be moved to mapme.c, but header size still in use in VPP */ -/* - * The length of the MAPME4 header struct must be bytes. - */ +#define EXPECTED_MAPME_V4_HDRLEN 120 #define EXPECTED_MAPME_V6_HDRLEN 88 -/** @brief MAP-Me packet header for IPv6 */ -typedef struct -{ - _ipv6_header_t ip; - _icmprd_header_t icmp_rd; - seq_t seq; - u8 len; - u8 _pad[3]; -} hicn_mapme_v6_header_t; - -/** @brief MAP-Me packet header (IP version agnostic) */ -typedef union -{ - hicn_mapme_v4_header_t v4; - hicn_mapme_v6_header_t v6; -} hicn_mapme_header_t; - -#define HICN_MAPME_V4_HDRLEN sizeof (hicn_mapme_v4_header_t) -#define HICN_MAPME_V6_HDRLEN sizeof (hicn_mapme_v6_header_t) - -static_assert (EXPECTED_MAPME_V4_HDRLEN == HICN_MAPME_V4_HDRLEN, - "Size of MAPME_V4 struct does not match its expected size."); -static_assert (EXPECTED_MAPME_V6_HDRLEN == HICN_MAPME_V6_HDRLEN, - "Size of MAPME_V6 struct does not match its expected size."); - #endif /* HICN_MAPME_H */ /* diff --git a/lib/includes/hicn/name.h b/lib/includes/hicn/name.h index f85b0bc3f..895b86341 100644 --- a/lib/includes/hicn/name.h +++ b/lib/includes/hicn/name.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -24,12 +24,14 @@ #ifndef HICN_NAME_H #define HICN_NAME_H +#include <assert.h> #include <stdbool.h> +#include <stddef.h> #ifndef _WIN32 #include <netinet/in.h> // struct sockadd #endif +#include <hicn/common.h> #include <hicn/util/ip_address.h> -#include "common.h" /****************************************************************************** * hICN names @@ -38,40 +40,92 @@ #define TCP_SEQNO_LEN 4 /* bytes */ #define HICN_V4_PREFIX_LEN IPV4_ADDR_LEN #define HICN_V6_PREFIX_LEN IPV6_ADDR_LEN -#define HICN_SEGMENT_LEN TCP_SEQNO_LEN + +#if 0 +#define HICN_SEGMENT_LEN TCP_SEQNO_LEN + #define HICN_V6_NAME_LEN \ (HICN_V6_PREFIX_LEN + HICN_SEGMENT_LEN) /* 20 bytes \ */ #define HICN_V4_NAME_LEN \ (HICN_V4_PREFIX_LEN + HICN_SEGMENT_LEN) /* 8 bytes \ */ +#endif + +#define HICN_INVALID_SUFFIX ((uint32_t) (~0)) /* Prefix */ -typedef u32 hicn_name_suffix_t; +#define HICN_PREFIX_MAX_LEN IP_ADDRESS_MAX_LEN typedef struct { - ip_address_t name; + hicn_ip_address_t name; u8 len; } hicn_prefix_t; +#define HICN_PREFIX_EMPTY \ + (hicn_prefix_t) { .name = IP_ADDRESS_EMPTY, .len = 0 } + +static inline const hicn_ip_address_t * +hicn_prefix_get_ip_address (const hicn_prefix_t *prefix) +{ + return &prefix->name; +} + +static inline u8 +hicn_prefix_get_len (const hicn_prefix_t *prefix) +{ + return prefix->len; +} + +int hicn_prefix_get_ip_prefix (const hicn_prefix_t *prefix, + hicn_ip_prefix_t *ip_prefix); /* * Name * * A name is a prefix + a segment name (suffix) */ +typedef hicn_ip_address_t hicn_name_prefix_t; +typedef uint32_t hicn_name_suffix_t; + +#define hicn_name_prefix_cmp hicn_ip_address_cmp +#define hicn_name_prefix_equals hicn_ip_address_equals +#define hicn_name_prefix_get_len_bits hicn_ip_address_get_len_bits +#define hicn_name_prefix_get_hash hicn_ip_address_get_hash +#define hicn_name_prefix_snprintf hicn_ip_address_snprintf +#define HICN_NAME_PREFIX_EMPTY IP_ADDRESS_EMPTY + typedef struct { - ip_address_t prefix; + hicn_name_prefix_t prefix; hicn_name_suffix_t suffix; } hicn_name_t; +static_assert (offsetof (hicn_name_t, prefix) == 0, ""); +static_assert (offsetof (hicn_name_t, suffix) == 16, ""); +static_assert (sizeof (hicn_name_t) == 20, ""); + +#define HICN_NAME_EMPTY \ + (hicn_name_t) { .prefix = HICN_NAME_PREFIX_EMPTY, .suffix = 0, } + +static inline const hicn_name_prefix_t * +hicn_name_get_prefix (const hicn_name_t *name) +{ + return &name->prefix; +} + +static inline const hicn_name_suffix_t +hicn_name_get_suffix (const hicn_name_t *name) +{ + return name->suffix; +} + #define _is_unspec(name) \ (((name)->prefix.pad[0] | (name)->prefix.pad[1] | (name)->prefix.pad[2] | \ (name)->prefix.v4.as_u32) == 0) -#define _is_inet4(name) (ip_address_is_v4 (&name->prefix)) +#define _is_inet4(name) (hicn_ip_address_is_v4 (&name->prefix)) #define _is_inet6(name) (!_is_inet4 (name)) /** @@ -86,11 +140,21 @@ int hicn_name_create (const char *ip_address, u32 id, hicn_name_t *name); /** * @brief Create an hICN name from IP address * @param [in] ip_address - IP address - * @param [in] id Segment - identifier + * @param [in] suffix - Name suffix * @param [out] Resulting - hICN name * @return hICN error code */ -int hicn_name_create_from_ip_prefix (const ip_prefix_t *prefix, u32 id, +int hicn_name_create_from_ip_address (const hicn_ip_address_t ip_address, + u32 suffix, hicn_name_t *name); + +/** + * @brief Create an hICN name from IP prefix + * @param [in] prefix - IP prefix + * @param [in] suffix - Name suffix + * @param [out] Resulting - hICN name + * @return hICN error code + */ +int hicn_name_create_from_ip_prefix (const hicn_ip_prefix_t *prefix, u32 id, hicn_name_t *name); /** @@ -113,7 +177,10 @@ int hicn_name_compare (const hicn_name_t *name_1, const hicn_name_t *name_2, * @param [in] consider_suffix - Consider the suffix in the hash computation * @return hICN error code */ -int hicn_name_hash (const hicn_name_t *name, u32 *hash, bool consider_suffix); +uint32_t _hicn_name_get_hash (const hicn_name_t *name, bool consider_suffix); + +#define hicn_name_get_hash(NAME) _hicn_name_get_hash (NAME, true) +#define hicn_name_get_prefix_hash(NAME) _hicn_name_get_hash (NAME, false) /** * @brief Test whether an hICN name is empty @@ -146,7 +213,7 @@ int hicn_name_copy_prefix_to_destination (u8 *dst, const hicn_name_t *src); * @param [in] seq_number - Segment identifier * @return hICN error code */ -int hicn_name_set_seq_number (hicn_name_t *name, u32 seq_number); +int hicn_name_set_suffix (hicn_name_t *name, hicn_name_suffix_t suffix); /** * @brief Retrieves the segment part of an hICN name @@ -171,7 +238,8 @@ int hicn_name_to_sockaddr_address (const hicn_name_t *name, * @param [out] ip_address - Resulting IP address * @return hICN error code */ -int hicn_name_to_ip_prefix (const hicn_name_t *name, ip_prefix_t *ip_prefix); +int hicn_name_to_hicn_ip_prefix (const hicn_name_t *name, + hicn_ip_prefix_t *hicn_ip_prefix); /** * @brief Convert an hICN name to presentation format @@ -198,15 +266,50 @@ int hicn_name_pton (const char *src, hicn_name_t *dst); */ int hicn_name_get_family (const hicn_name_t *name, int *family); +bool hicn_name_is_v4 (const hicn_name_t *name); + +int hicn_name_snprintf (char *s, size_t size, const hicn_name_t *name); + +int hicn_name_cmp (const hicn_name_t *n1, const hicn_name_t *n2); +bool hicn_name_equals (const hicn_name_t *n1, const hicn_name_t *n2); + +#define MAXSZ_HICN_NAME MAXSZ_IP_ADDRESS + /** * @brief Creates an hICN prefix from an IP address * @param [in] ip_address - Input IP address * @param [out] prefix - Resulting prefix * @return hICN error code */ -int hicn_prefix_create_from_ip_prefix (const ip_prefix_t *ip_prefix, +int hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix, hicn_prefix_t *prefix); +int +hicn_prefix_create_from_ip_address_len (const hicn_ip_address_t *ip_address, + uint8_t len, hicn_prefix_t *prefix); + +hicn_prefix_t *hicn_prefix_dup (const hicn_prefix_t *prefix); + +int hicn_prefix_copy (hicn_prefix_t *dst, const hicn_prefix_t *src); + +bool hicn_prefix_is_v4 (const hicn_prefix_t *prefix); + +uint32_t hicn_prefix_lpm (const hicn_prefix_t *p1, const hicn_prefix_t *p2); + +void hicn_prefix_clear (hicn_prefix_t *prefix, uint8_t start_from); + +void hicn_prefix_truncate (hicn_prefix_t *prefix, uint8_t len); + +int hicn_prefix_cmp (const hicn_prefix_t *p1, const hicn_prefix_t *p2); + +bool hicn_prefix_equals (const hicn_prefix_t *p1, const hicn_prefix_t *p2); + +int hicn_prefix_snprintf (char *s, size_t size, const hicn_prefix_t *prefix); + +uint8_t hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos); + +#define MAXSZ_HICN_PREFIX MAXSZ_IP_PREFIX + #endif /* HICN_NAME_H */ /* diff --git a/lib/includes/hicn/ops.h b/lib/includes/hicn/ops.h deleted file mode 100644 index 4efef6523..000000000 --- a/lib/includes/hicn/ops.h +++ /dev/null @@ -1,1029 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file base.h - * @brief Protocol-independent packet operations - */ - -#ifndef HICN_OPS_H -#define HICN_OPS_H - -#include <stdlib.h> - -#include "common.h" -#include "error.h" -#include "header.h" -#include "name.h" - -/* - * hICN operations on packets - * - * All prototypes take an hicn_type_t parameter as their first argument, as - * this decides the sequence of protocols that are being used by the different - * operations. - */ - -typedef struct hicn_ops_s -{ - /** - * @brief Initialize the headers of the hicn packet - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the packet - */ - int (*init_packet_header) (hicn_type_t type, hicn_protocol_t *h); - - /** - * @brief Retrieves an Interest locator - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest packet - * @param [out] ip_address - Retrieved locator - * @return hICN error code - */ - int (*get_interest_locator) (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address); - - /** - * @brief Sets an Interest locator - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest packet - * @param [in] ip_address - Locator to set - * @return hICN error code - */ - int (*set_interest_locator) (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address); - - /** - * @brief Retrieves an Interest name - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest packet - * @param [out] name - Retrieved name - * @return hICN error code - */ - int (*get_interest_name) (hicn_type_t type, const hicn_protocol_t *h, - hicn_name_t *name); - - /** - * @brief Sets an Interest name - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest packet - * @param [in] name - Name to set - * @return hICN error code - */ - int (*set_interest_name) (hicn_type_t type, hicn_protocol_t *h, - const hicn_name_t *name); - - /** - * @brief Retrieves an Interest name suffix - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest packet - * @param [out] suffix - Retrieved name suffix - * @return hICN error code - */ - int (*get_interest_name_suffix) (hicn_type_t type, const hicn_protocol_t *h, - hicn_name_suffix_t *suffix); - - /** - * @brief Sets an Interest name suffix - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest packet - * @param [in] suffix - Name suffix to set - * @return hICN error code - */ - int (*set_interest_name_suffix) (hicn_type_t type, hicn_protocol_t *h, - const hicn_name_suffix_t *suffix); - - /** - * @brief Check if packet is an interest - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest packet - * @param [out] h - 1 if interest, 0 otherwise - * @return hICN error code - */ - int (*is_interest) (hicn_type_t type, const hicn_protocol_t *h, int *ret); - - /** - * @brief Set flag to mark current packet as interest - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest packet - * @return hICN error code - */ - int (*mark_packet_as_interest) (hicn_type_t type, hicn_protocol_t *h); - - /** - * @brief Set flag to mark current packet as data - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest packet - * @return hICN error code - */ - int (*mark_packet_as_data) (hicn_type_t type, hicn_protocol_t *h); - - /** - * @brief Clear the necessary Interest fields in order to hash it - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest packet - * @return hICN error code - */ - int (*reset_interest_for_hash) (hicn_type_t type, hicn_protocol_t *h); - - /** - * @brief Retrieves a Data locator - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Data packet - * @param [out] ip_address - Retrieved locator - * @return hICN error code - */ - int (*get_data_locator) (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address); - - /** - * @brief Sets a Data locator - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Data packet - * @param [in] ip_address - Locator to set - * @return hICN error code - */ - int (*set_data_locator) (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address); - - /** - * @brief Retrieves a Data name - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Data packet - * @param [out] name - Retrieved name - * @return hICN error code - */ - int (*get_data_name) (hicn_type_t type, const hicn_protocol_t *h, - hicn_name_t *name); - - /** - * @brief Sets a Data name - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Data packet - * @param [in] name - Name to set - * @return hICN error code - */ - int (*set_data_name) (hicn_type_t type, hicn_protocol_t *h, - const hicn_name_t *name); - - /** - * @brief Retrieves a Data name suffix - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Data packet - * @param [out] suffix - Retrieved name suffix - * @return hICN error code - */ - int (*get_data_name_suffix) (hicn_type_t type, const hicn_protocol_t *h, - hicn_name_suffix_t *suffix); - - /** - * @brief Sets a Data name suffix - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Data packet - * @param [in] suffix - Name suffix to set - * @return hICN error code - */ - int (*set_data_name_suffix) (hicn_type_t type, hicn_protocol_t *h, - const hicn_name_suffix_t *suffix); - - /** - * @brief Retrieves a Data pathlabel - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Data packet - * @param [out] pathlabel - Retrieved pathlabel - * @return hICN error code - */ - int (*get_data_pathlabel) (hicn_type_t type, const hicn_protocol_t *h, - u32 *pathlabel); - - /** - * @brief Sets a Data pathlabel - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Data packet - * @param [in] pathlabel - Pathlabel to set - * @return hICN error code - */ - int (*set_data_pathlabel) (hicn_type_t type, hicn_protocol_t *h, - const u32 pathlabel); - - /** - * @brief Update a Data pathlabel with a new face identifier - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Data packet - * @param [in] pathlabel - Face identifier used to update pathlabel - * @return hICN error code - */ - int (*update_data_pathlabel) (hicn_type_t type, hicn_protocol_t *h, - const hicn_faceid_t face_id); - - /** - * @brief Clear the necessary Data fields in order to hash it - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Data packet - * @return hICN error code - */ - int (*reset_data_for_hash) (hicn_type_t type, hicn_protocol_t *h); - - /** - * @brief Retrieves an Interest or Data lifetime - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] pathlabel - Retrieved lifetime - * @return hICN error code - */ - int (*get_lifetime) (hicn_type_t type, const hicn_protocol_t *h, - hicn_lifetime_t *lifetime); - - /** - * @brief Sets an Interest or Data lifetime - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] pathlabel - Lifetime to set - * @return hICN error code - */ - int (*set_lifetime) (hicn_type_t type, hicn_protocol_t *h, - const hicn_lifetime_t lifetime); - - /** - * @brief Get the source port of the hicn packet. - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] source_port - Retrieved source port - * @return hICN error code - */ - int (*get_source_port) (hicn_type_t type, const hicn_protocol_t *h, - u16 *source_port); - - /** - * @brief Get the destination port of the hicn packet. - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] source_port - Retrieved destination port - * @return hICN error code - */ - int (*get_dest_port) (hicn_type_t type, const hicn_protocol_t *h, - u16 *dest_port); - - /** - * @brief Set the source port of the hicn packet. - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] source_port - Source port to set - * @return hICN error code - */ - int (*set_source_port) (hicn_type_t type, hicn_protocol_t *h, - u16 source_port); - - /** - * @brief Set the destination port of the hicn packet. - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] source_port - Destination port to set - * @return hICN error code - */ - int (*set_dest_port) (hicn_type_t type, hicn_protocol_t *h, u16 dest_port); - - /** - * @brief Update all checksums in packet headers - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the packet - * @param [in] partial_csum - Partial checksum (set to 0, used internally to - * carry intermediate values from IP pseudo-header) - * @param [in] payload_length - Payload length (can be set to ~0, retrieved - * and used internally to carry payload length across protocol headers) - * @return hICN error code - */ - int (*update_checksums) (hicn_type_t type, hicn_protocol_t *h, - u16 partial_csum, size_t payload_length); - - /** - * @brief Validate all checksums in packet headers - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the packet - * @param [in] partial_csum - Partial checksum, or zero if no partial - * checksum available - * @param [in] payload_length - Payload length (can be set to ~0, retrieved - * and used internally to carry payload length across protocol headers) - * @return hICN error code - */ - int (*verify_checksums) (hicn_type_t type, hicn_protocol_t *h, - u16 partial_csum, size_t payload_length); - - /** - * @brief Rewrite an Interest packet header (locator) - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest packet - * @param [in] addr_new - New locator - * @param [in] addr_old - Old locator (set to NULL, used internally to - * compute incremental checksums) - * @return hICN error code - */ - int (*rewrite_interest) (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, - ip_address_t *addr_old); - - /** - * @brief Rewrite a Data packet header (locator + pathlabel) - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Data packet - * @param [in] addr_new - New locator - * @param [in] addr_old - Old locator (set to NULL, used internally to - * compute incremental checksums) - * @param [in] face_id - Face identifier used to update pathlabel - * @param [in] reset_pl - If not zero, reset the current pathlabel - * before update it - * @return hICN error code - */ - int (*rewrite_data) (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl); - - /** - * @brief Return the packet length - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the packet - * @parma [out] length - Returned packet length - * @return hICN error code - */ - int (*get_length) (hicn_type_t type, const hicn_protocol_t *h, - size_t *length); - - /** - * @brief Return the current packet header length - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the packet - * @parma [out] header_length - Returned packet current header length - * @return hICN error code - */ - int (*get_current_header_length) (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length); - - /** - * @brief Return the packet header length - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the packet - * @parma [out] header_length - Returned packet header length - * @return hICN error code - */ - int (*get_header_length) (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length); - - /** - * @brief Return the packet payload length - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the packet - * @parma [out] payload_length - Returned packet payload length - * @return hICN error code - */ - int (*get_payload_length) (hicn_type_t type, const hicn_protocol_t *h, - size_t *payload_length); - - /** - * @brief Sets the packet paylaod length - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the packet - * @parma [out] payload_length - Payload length to set - * @return hICN error code - */ - int (*set_payload_length) (hicn_type_t type, hicn_protocol_t *h, - size_t payload_length); - - /** - * @brief Retrieves an Interest or Data signature size - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] signature_size - Retrieved signature size - * @return hICN error code - */ - int (*get_signature_size) (hicn_type_t type, const hicn_protocol_t *h, - size_t *signature_size); - - /** - * @brief Sets an Interest or Data signature size - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] signature_size - Signature size to set - * @return hICN error code - */ - int (*set_signature_size) (hicn_type_t type, hicn_protocol_t *h, - size_t signature_size); - - /** - * @brief Sets an Interest or Data signature padding between maximum size and - * real size - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] signature_size - Signature size to set - * @return hICN error code - */ - int (*set_signature_padding) (hicn_type_t type, hicn_protocol_t *h, - size_t signature_padding); - - /** - * @brief gets an Interest or Data signature padding between maximum size and - * real size - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] signature_size - retrieve the padding between maximum size and - * real size - * @return hICN error code - */ - int (*get_signature_padding) (hicn_type_t type, const hicn_protocol_t *h, - size_t *signature_padding); - - /** - * @brief Gets the signature timestamp - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [out] signature_timestamp - Retrieved signature timestamp - * @return hICN error code - */ - int (*get_signature_timestamp) (hicn_type_t type, const hicn_protocol_t *h, - uint64_t *signature_timestamp); - - /** - * @brief Sets the signature timestamp - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] signature_timestamp - Signature timestamp to set - * @return hICN error code - */ - int (*set_signature_timestamp) (hicn_type_t type, hicn_protocol_t *h, - uint64_t signature_timestamp); - - /** - * @brief Gets the signature validation algorithm - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [out] validation_algorithm - Retrieved validation_algorithm - * @return hICN error code - */ - int (*get_validation_algorithm) (hicn_type_t type, const hicn_protocol_t *h, - uint8_t *validation_algorithm); - - /** - * @brief Sets the signature validation algorithm - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] validation_algorithm - Validation algorithm enumeration - * @return hICN error code - */ - int (*set_validation_algorithm) (hicn_type_t type, hicn_protocol_t *h, - uint8_t validation_algorithm); - - /** - * @brief Gets the key id - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [out] key_id - Retrieved key id first byte address - * @return hICN error code - */ - int (*get_key_id) (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size); - - /** - * @brief Sets the key id - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] key_id - Key id first byte address - * @return hICN error code - */ - int (*set_key_id) (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id); - - /** - * @brief Get a pointer to the signature field in the packet - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [out] signature - Pointer to the memory region holding the - * signature - * @return hICN error code - */ - int (*get_signature) (hicn_type_t type, hicn_protocol_t *h, - uint8_t **signature); - - /** - * @brief Set payload type of the packet - * @param [in] type - hICN packet type - * @param [in,out] h - Buffer holding the Interest or Data packet - * @param [in] payload_type - The payload type of this packet - * @return hICN error code - */ - int (*set_payload_type) (hicn_type_t type, hicn_protocol_t *h, - hicn_payload_type_t payload_type); - - /** - * @brief Get payload type from the packet - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] payload_type - The payload type of this packet - * @return hICN error code - */ - int (*get_payload_type) (hicn_type_t type, const hicn_protocol_t *h, - hicn_payload_type_t *payload_type); - - /** - * @brief Check if data packet is last one. - * @param [in] type - hICN packet type - * @param [in] h - Buffer holding the Interest or Data packet - * @param [out] is_last - 1 if last data, 0 otherwise - * @return hICN error code - */ - int (*is_last_data) (hicn_type_t type, const hicn_protocol_t *h, - int *is_last); - - /** - * @brief Mark data packet as last - * @param [in] type - hICN packet type - * @param [in, out] h - Buffer holding the Interest or Data packet - * @return hICN error code - */ - int (*set_last_data) (hicn_type_t type, hicn_protocol_t *h); -} hicn_ops_t; - -#define DECLARE_HICN_OPS(protocol) \ - const hicn_ops_t hicn_ops_##protocol = { \ - ATTR_INIT (init_packet_header, protocol##_init_packet_header), \ - ATTR_INIT (get_interest_locator, protocol##_get_interest_locator), \ - ATTR_INIT (set_interest_locator, protocol##_set_interest_locator), \ - ATTR_INIT (get_interest_name, protocol##_get_interest_name), \ - ATTR_INIT (set_interest_name, protocol##_set_interest_name), \ - ATTR_INIT (get_interest_name_suffix, \ - protocol##_get_interest_name_suffix), \ - ATTR_INIT (set_interest_name_suffix, \ - protocol##_set_interest_name_suffix), \ - ATTR_INIT (is_interest, protocol##_is_interest), \ - ATTR_INIT (mark_packet_as_interest, protocol##_mark_packet_as_interest), \ - ATTR_INIT (mark_packet_as_data, protocol##_mark_packet_as_data), \ - ATTR_INIT (reset_interest_for_hash, protocol##_reset_interest_for_hash), \ - ATTR_INIT (get_data_locator, protocol##_get_data_locator), \ - ATTR_INIT (set_data_locator, protocol##_set_data_locator), \ - ATTR_INIT (get_data_name, protocol##_get_data_name), \ - ATTR_INIT (set_data_name, protocol##_set_data_name), \ - ATTR_INIT (get_data_name_suffix, protocol##_get_data_name_suffix), \ - ATTR_INIT (set_data_name_suffix, protocol##_set_data_name_suffix), \ - ATTR_INIT (get_data_pathlabel, protocol##_get_data_pathlabel), \ - ATTR_INIT (set_data_pathlabel, protocol##_set_data_pathlabel), \ - ATTR_INIT (update_data_pathlabel, protocol##_update_data_pathlabel), \ - ATTR_INIT (reset_data_for_hash, protocol##_reset_data_for_hash), \ - ATTR_INIT (get_lifetime, protocol##_get_lifetime), \ - ATTR_INIT (set_lifetime, protocol##_set_lifetime), \ - ATTR_INIT (get_source_port, protocol##_get_source_port), \ - ATTR_INIT (get_dest_port, protocol##_get_dest_port), \ - ATTR_INIT (set_source_port, protocol##_set_source_port), \ - ATTR_INIT (set_dest_port, protocol##_set_dest_port), \ - ATTR_INIT (update_checksums, protocol##_update_checksums), \ - ATTR_INIT (verify_checksums, protocol##_verify_checksums), \ - ATTR_INIT (rewrite_interest, protocol##_rewrite_interest), \ - ATTR_INIT (rewrite_data, protocol##_rewrite_data), \ - ATTR_INIT (get_length, protocol##_get_length), \ - ATTR_INIT (get_current_header_length, \ - protocol##_get_current_header_length), \ - ATTR_INIT (get_header_length, protocol##_get_header_length), \ - ATTR_INIT (get_payload_length, protocol##_get_payload_length), \ - ATTR_INIT (set_payload_length, protocol##_set_payload_length), \ - ATTR_INIT (get_payload_type, protocol##_get_payload_type), \ - ATTR_INIT (set_payload_type, protocol##_set_payload_type), \ - ATTR_INIT (get_signature_size, protocol##_get_signature_size), \ - ATTR_INIT (get_signature_timestamp, protocol##_get_signature_timestamp), \ - ATTR_INIT (set_signature_timestamp, protocol##_set_signature_timestamp), \ - ATTR_INIT (get_validation_algorithm, \ - protocol##_get_validation_algorithm), \ - ATTR_INIT (set_validation_algorithm, \ - protocol##_set_validation_algorithm), \ - ATTR_INIT (get_key_id, protocol##_get_key_id), \ - ATTR_INIT (set_key_id, protocol##_set_key_id), \ - ATTR_INIT (get_signature, protocol##_get_signature), \ - ATTR_INIT (set_signature_padding, protocol##_set_signature_padding), \ - ATTR_INIT (set_signature_size, protocol##_set_signature_size), \ - ATTR_INIT (get_signature_padding, protocol##_get_signature_padding), \ - ATTR_INIT (is_last_data, protocol##_is_last_data), \ - ATTR_INIT (set_last_data, protocol##_set_last_data), \ - } - -/** - * @brief Protocol-independent packet operations VFT - * NOTE: The following declarations should be kept in order - */ -extern const hicn_ops_t *const hicn_ops_vft[]; - -/* - * Helpers for writing recursive protocol operations on packet headers - * - * NOTE : we cannot use a shift operation as IPPROTO_NONE != 0 (and 0 is - * IPv4...) - */ -static inline hicn_type_t -TYPE_POP (hicn_type_t type) -{ -#ifndef _WIN32 - return HICN_TYPE (type.l2, type.l3, type.l4, IPPROTO_NONE); -#else - hicn_type_t new_type; - new_type.l1 = type.l2; - new_type.l2 = type.l3; - new_type.l3 = type.l4; - new_type.l4 = IPPROTO_NONE; - return new_type; -#endif -} - -static inline hicn_protocol_t * -PAYLOAD (hicn_type_t type, const hicn_protocol_t *h) -{ - size_t header_length; - int rc = - hicn_ops_vft[type.l1]->get_current_header_length (type, h, &header_length); - if (rc < 0) - return NULL; - return (hicn_protocol_t *) ((u8 *) h + header_length); -} - -#define CHILD_OPS(f, type, h, ...) \ - (hicn_ops_vft[type.l2]->f (TYPE_POP (type), PAYLOAD (type, h), \ - ##__VA_ARGS__)) - -/** Shortcuts to entry points in VFT */ -#define HICN_OPS4 hicn_ops_vft[IPPROTO_IP] -#define HICN_OPS6 hicn_ops_vft[IPPROTO_IPV6] - -/* Helpers for simple declarations */ - -#define DECLARE_init_packet_header(protocol, error) \ - int protocol##_init_packet_header (hicn_type_t type, hicn_protocol_t *h) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_interest_locator(protocol, error) \ - int protocol##_get_interest_locator ( \ - hicn_type_t type, const hicn_protocol_t *h, ip_address_t *ip_address) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_interest_locator(protocol, error) \ - int protocol##_set_interest_locator (hicn_type_t type, hicn_protocol_t *h, \ - const ip_address_t *ip_address) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_interest_name(protocol, error) \ - int protocol##_get_interest_name ( \ - hicn_type_t type, const hicn_protocol_t *h, hicn_name_t *name) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_interest_name(protocol, error) \ - int protocol##_set_interest_name (hicn_type_t type, hicn_protocol_t *h, \ - const hicn_name_t *name) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_interest_name_suffix(protocol, error) \ - int protocol##_get_interest_name_suffix ( \ - hicn_type_t type, const hicn_protocol_t *h, hicn_name_suffix_t *suffix) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_interest_name_suffix(protocol, error) \ - int protocol##_set_interest_name_suffix ( \ - hicn_type_t type, hicn_protocol_t *h, const hicn_name_suffix_t *suffix) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_is_interest(protocol, error) \ - int protocol##_is_interest (hicn_type_t type, const hicn_protocol_t *h, \ - int *ret) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_mark_packet_as_interest(protocol, error) \ - int protocol##_mark_packet_as_interest (hicn_type_t type, \ - hicn_protocol_t *h) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_mark_packet_as_data(protocol, error) \ - int protocol##_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_reset_interest_for_hash(protocol, error) \ - int protocol##_reset_interest_for_hash (hicn_type_t type, \ - hicn_protocol_t *h) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_data_locator(protocol, error) \ - int protocol##_get_data_locator ( \ - hicn_type_t type, const hicn_protocol_t *h, ip_address_t *ip_address) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_data_locator(protocol, error) \ - int protocol##_set_data_locator (hicn_type_t type, hicn_protocol_t *h, \ - const ip_address_t *ip_address) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_data_name(protocol, error) \ - int protocol##_get_data_name (hicn_type_t type, const hicn_protocol_t *h, \ - hicn_name_t *name) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_data_name(protocol, error) \ - int protocol##_set_data_name (hicn_type_t type, hicn_protocol_t *h, \ - const hicn_name_t *name) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_data_name_suffix(protocol, error) \ - int protocol##_get_data_name_suffix ( \ - hicn_type_t type, const hicn_protocol_t *h, hicn_name_suffix_t *suffix) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_data_name_suffix(protocol, error) \ - int protocol##_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, \ - const hicn_name_suffix_t *suffix) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_data_pathlabel(protocol, error) \ - int protocol##_get_data_pathlabel ( \ - hicn_type_t type, const hicn_protocol_t *h, u32 *pathlabel) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_data_pathlabel(protocol, error) \ - int protocol##_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, \ - const u32 pathlabel) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_update_data_pathlabel(protocol, error) \ - int protocol##_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, \ - const hicn_faceid_t face_id) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_reset_data_for_hash(protocol, error) \ - int protocol##_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_lifetime(protocol, error) \ - int protocol##_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, \ - hicn_lifetime_t *lifetime) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_lifetime(protocol, error) \ - int protocol##_set_lifetime (hicn_type_t type, hicn_protocol_t *h, \ - const hicn_lifetime_t lifetime) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_source_port(protocol, error) \ - int protocol##_get_source_port (hicn_type_t type, const hicn_protocol_t *h, \ - u16 *source_port) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_dest_port(protocol, error) \ - int protocol##_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, \ - u16 *dest_port) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_source_port(protocol, error) \ - int protocol##_set_source_port (hicn_type_t type, hicn_protocol_t *h, \ - u16 source_port) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_dest_port(protocol, error) \ - int protocol##_set_dest_port (hicn_type_t type, hicn_protocol_t *h, \ - u16 dest_port) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_update_checksums(protocol, error) \ - int protocol##_update_checksums (hicn_type_t type, hicn_protocol_t *h, \ - u16 partial_csum, size_t payload_length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_verify_checksums(protocol, error) \ - int protocol##_verify_checksums (hicn_type_t type, hicn_protocol_t *h, \ - u16 partial_csum, size_t payload_length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_rewrite_interest(protocol, error) \ - int protocol##_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, \ - const ip_address_t *addr_new, \ - ip_address_t *addr_old) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_rewrite_data(protocol, error) \ - int protocol##_rewrite_data ( \ - hicn_type_t type, hicn_protocol_t *h, const ip_address_t *addr_new, \ - ip_address_t *addr_old, const hicn_faceid_t face_id, u8 reset_pl) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_length(protocol, error) \ - int protocol##_get_length (hicn_type_t type, const hicn_protocol_t *h, \ - size_t *length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_current_header_length(protocol, error) \ - int protocol##_get_current_header_length ( \ - hicn_type_t type, const hicn_protocol_t *h, size_t *header_length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_header_length(protocol, error) \ - int protocol##_get_header_length ( \ - hicn_type_t type, const hicn_protocol_t *h, size_t *header_length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_payload_length(protocol, error) \ - int protocol##_get_payload_length ( \ - hicn_type_t type, const hicn_protocol_t *h, size_t *payload_length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_payload_length(protocol, error) \ - int protocol##_set_payload_length (hicn_type_t type, hicn_protocol_t *h, \ - size_t payload_length) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_payload_type(protocol, error) \ - int protocol##_get_payload_type (hicn_type_t type, \ - const hicn_protocol_t *h, \ - hicn_payload_type_t *payload_type) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_payload_type(protocol, error) \ - int protocol##_set_payload_type (hicn_type_t type, hicn_protocol_t *h, \ - hicn_payload_type_t payload_type) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_signature_size(protocol, error) \ - int protocol##_get_signature_size ( \ - hicn_type_t type, const hicn_protocol_t *h, size_t *signature_size) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_signature_size(protocol, error) \ - int protocol##_set_signature_size (hicn_type_t type, hicn_protocol_t *h, \ - size_t signature_size) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_signature_padding(protocol, error) \ - int protocol##_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, \ - size_t padding) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_signature_padding(protocol, error) \ - int protocol##_get_signature_padding ( \ - hicn_type_t type, const hicn_protocol_t *h, size_t *padding) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_signature_timestamp(protocol, error) \ - int protocol##_set_signature_timestamp ( \ - hicn_type_t type, hicn_protocol_t *h, uint64_t signature_timestamp) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_signature_timestamp(protocol, error) \ - int protocol##_get_signature_timestamp (hicn_type_t type, \ - const hicn_protocol_t *h, \ - uint64_t *signature_timestamp) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_validation_algorithm(protocol, error) \ - int protocol##_set_validation_algorithm ( \ - hicn_type_t type, hicn_protocol_t *h, uint8_t validation_algorithm) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_validation_algorithm(protocol, error) \ - int protocol##_get_validation_algorithm (hicn_type_t type, \ - const hicn_protocol_t *h, \ - uint8_t *validation_algorithm) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_key_id(protocol, error) \ - int protocol##_set_key_id (hicn_type_t type, hicn_protocol_t *h, \ - uint8_t *key_id) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_key_id(protocol, error) \ - int protocol##_get_key_id (hicn_type_t type, hicn_protocol_t *h, \ - uint8_t **key_id, uint8_t *key_id_size) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_get_signature(protocol, error) \ - int protocol##_get_signature (hicn_type_t type, hicn_protocol_t *h, \ - uint8_t **signature) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_is_last_data(protocol, error) \ - int protocol##_is_last_data (hicn_type_t type, const hicn_protocol_t *h, \ - int *is_last) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#define DECLARE_set_last_data(protocol, error) \ - int protocol##_set_last_data (hicn_type_t type, hicn_protocol_t *h) \ - { \ - return HICN_LIB_ERROR_##error; \ - } - -#endif /* HICN_OPS_H */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/lib/includes/hicn/packet.h b/lib/includes/hicn/packet.h new file mode 100644 index 000000000..c64014fe6 --- /dev/null +++ b/lib/includes/hicn/packet.h @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2017-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file compat.h + * @brief Implementation of the compatibility layer. + * + * The structure of the core API has evolved to support operations of a variety + * of packet formats in addition to IPv4/TCP and IPv6/TCP, namely with the use + * of ICMP for signalization and AH headers for integrity. The new API format + * has been designed to scale better with the multiplicity of packet formats, + * and provide a unified interface on top. We maintain an interface for the + * former API in this file, which mainly acts as a wrapper on top of new calls. + * + */ +#ifndef HICN_PACKET_H +#define HICN_PACKET_H + +#include <limits.h> + +#include <hicn/base.h> +#include <hicn/common.h> +#include <hicn/name.h> + +/* Packet buffer definition */ + +typedef struct __attribute__ ((packed)) +{ + /* Packet format */ + hicn_packet_format_t format; + + /* Packet type */ + hicn_packet_type_t type; + + /* + * We store an offset to the packet header. + * + * NOTE: This is a signed value. + * + * In most implementations, the buffer located closeby to the current packet + * buffer (eg msgbuf in hicn-light, and vlib buffer in VPP), and an int16_t + * would be sufficient. This is not the case in transport though and we have + * to use a full integer. + */ + int64_t header; + + /* Packet len */ + uint16_t len; + +#ifdef OPAQUE_IP + /* Interest or data packet */ + union + { + uint16_t ipv4; + uint16_t ipv6; + }; +#endif /* OPAQUE_IP */ + union + { + uint16_t tcp; + uint16_t udp; + uint16_t icmp; + }; + uint16_t newhdr; + uint16_t ah; + uint16_t payload; + + uint16_t buffer_size; + // uint16_t len; + + /* Contiguous copy of the name */ + // hicn_name_t *name; + +} hicn_packet_buffer_t; + +static_assert (sizeof (hicn_packet_buffer_t) == 28, ""); + +static inline uint8_t * +_pkbuf_get_ipv4 (const hicn_packet_buffer_t *pkbuf) +{ +#ifdef OPAQUE_IP + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->ipv4; +#else + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header; +#endif + _ASSERT (header); + return header; +} +#define pkbuf_get_ipv4(pkbuf) ((_ipv4_header_t *) (_pkbuf_get_ipv4 (pkbuf))) + +static inline uint8_t * +_pkbuf_get_ipv6 (const hicn_packet_buffer_t *pkbuf) +{ +#ifdef OPAQUE_IP + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->ipv6; +#else + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header; +#endif + assert (header); + return header; +} +#define pkbuf_get_ipv6(pkbuf) ((_ipv6_header_t *) (_pkbuf_get_ipv6 (pkbuf))) + +static inline uint8_t * +_pkbuf_get_tcp (const hicn_packet_buffer_t *pkbuf) +{ + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->tcp; + assert (header); + return header; +} +#define pkbuf_get_tcp(pkbuf) ((_tcp_header_t *) (_pkbuf_get_tcp (pkbuf))) + +static inline uint8_t * +_pkbuf_get_udp (const hicn_packet_buffer_t *pkbuf) +{ + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->udp; + assert (header); + return header; +} +#define pkbuf_get_udp(pkbuf) ((_udp_header_t *) (_pkbuf_get_udp (pkbuf))) + +static inline uint8_t * +_pkbuf_get_icmp (const hicn_packet_buffer_t *pkbuf) +{ + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->icmp; + assert (header); + return header; +} +#define pkbuf_get_icmp(pkbuf) ((_icmp_header_t *) (_pkbuf_get_icmp (pkbuf))) + +static inline uint8_t * +_pkbuf_get_ah (const hicn_packet_buffer_t *pkbuf) +{ + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->ah; + assert (header); + return header; +} +#define pkbuf_get_ah(pkbuf) ((_ah_header_t *) (_pkbuf_get_ah (pkbuf))) + +static inline uint8_t * +_pkbuf_get_new (const hicn_packet_buffer_t *pkbuf) +{ + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header + pkbuf->newhdr; + assert (header); + return header; +} +#define pkbuf_get_new(pkbuf) ((_new_header_t *) (_pkbuf_get_new (pkbuf))) + +static inline uint8_t * +pkbuf_get_header (const hicn_packet_buffer_t *pkbuf) +{ + uint8_t *header = (uint8_t *) pkbuf + pkbuf->header; + assert (header); + return header; +} + +static inline void +pkbuf_set_header (hicn_packet_buffer_t *pkbuf, uint8_t *header) +{ + ssize_t offset = header - (uint8_t *) pkbuf; + assert (offset < INT64_MAX); + assert (offset > INT64_MIN); + pkbuf->header = (int64_t) offset; +} + +/* + * Packet buffer operations + * + * A packet buffer can either be initialized either: + * + * 1) from an empty buffer (packet crafting). + * + * #define MTU 1500 + * size_t size = MTU; + * u8 buffer[MTU]; + * + * hicn_packet_t pkbuf; + * hicn_packet_set_format(&pkbuf, HICN_PACKET_FORMAT_NEW); + * hicn_packet_set_buffer(&pkbuf, &buffer, size); + * hicn_packet_init_header(&pkbuf, 0); + * + * An empty (but correct) packet is not available in the buffer, ready to be + * modified and/or sent. + * + * 2) from an existing buffer (packet reception): + * + * hicn_packet_t pkbuf; + * hicn_packet_set_buffer(&pkbuf, &buffer, size); + * hicn_packet_analyze(&pkbuf); + * + * It is then possible to retrieve properties of the packet such as format and + * type (interest, data, etc.). + * + * hicn_packet_get_format(&pkbuf); + * hicn_packet_get_type(&pkbuf); + * + * */ + +hicn_packet_format_t +hicn_packet_get_format (const hicn_packet_buffer_t *pkbuf); + +void hicn_packet_set_format (hicn_packet_buffer_t *pkbuf, + hicn_packet_format_t format); + +hicn_packet_type_t hicn_packet_get_type (const hicn_packet_buffer_t *pkbuf); +void hicn_packet_set_type (hicn_packet_buffer_t *pkbuf, + hicn_packet_type_t type); + +bool hicn_packet_is_interest (const hicn_packet_buffer_t *pkbuf); + +bool hicn_packet_is_data (const hicn_packet_buffer_t *pkbuf); + +bool hicn_packet_is_undefined (const hicn_packet_buffer_t *pkbuf); + +/** + * @brief Initialize the buffer from packet buffer metadata (builds a valid + * packet). + * @param [in] pkbuf - hICN packet buffer + * @return hICN error code + * + * Packet type, format, and a buffer are required. + */ +int hicn_packet_init_header (hicn_packet_buffer_t *pkbuf, + size_t additional_header_size); + +/** + * @brief Reset information stored in the packet header. + * @param [in] pkbuf - hICN packet buffer + * @return hICN error code + */ +int hicn_packet_reset (hicn_packet_buffer_t *pkbuf); + +/** + * @brief Analyze buffer to populate metadata in packet buffer. + * @param [in] pkbuf - hICN packet buffer + * @return hICN error code + */ +int hicn_packet_analyze (hicn_packet_buffer_t *pkbuf); + +/** + * @brief Initialize hicn packet storage space with a buffer + * @param [in] pkbuf - hICN packet buffer + * @param [in] buffer - Packet storage buffer + * @param [in] analyze - Flag indicating whether to analyze the buffer + * content to populate packet format, header's offsets, etc. + * @return hICN error code + */ +int hicn_packet_set_buffer (hicn_packet_buffer_t *pkbuf, u8 *buffer, + uint16_t buffer_size, uint16_t len); + +/** + * @brief Retrieve the storage buffer. + * @param [in] pkbuf - hICN packet buffer + * @param [out] buffer - Packet buffer + * @param [out] buffer_size - Packet buffer size + * @return Pointer to storage buffer (this only returns the pointer; no copy is + * made) + */ +int hicn_packet_get_buffer (const hicn_packet_buffer_t *pkbuf, u8 **buffer, + uint16_t *buffer_size, uint16_t *len); + +/** + * @brief Retrieve the packet length + * @param [in] pkbuf - hICN packet buffer + * @return Length of the stored packet + */ +size_t hicn_packet_get_len (const hicn_packet_buffer_t *pkbuf); + +/** + * @brief Set the packet length + * @param [in] pkbuf - hICN packet buffer + * @param [in] len - hICN packet length + * @return None + */ +int hicn_packet_set_len (hicn_packet_buffer_t *pkbuf, size_t len); + +/** + * @brief Return total length of hicn headers (before payload) + * @param [in] pkbuf - hICN packet buffer + * @param [out] len - Total headers length + * @return Headers' len + */ +int hicn_packet_get_header_len (const hicn_packet_buffer_t *pkbuf, + size_t *len); + +/** + * @brief Return the length of hICN payload in the packet. + * @param [in] pkbuf - hICN packet buffer + * @param [out] len - hICN payload length + * @return Payload len + */ +int hicn_packet_get_payload_len (const hicn_packet_buffer_t *pkbuf, + size_t *len); + +/** + * @brief Sets the payload of a packet + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @param [in] payload - payload to set + * @param [in] payload_length - size of the payload to set + * @return hICN error code + * + * NOTE: + * - The buffer holding payload is assumed sufficiently large + * - This function updates header fields with the new length, but no checksum. + */ +int hicn_packet_set_payload (const hicn_packet_buffer_t *pkbuf, + const u8 *payload, u16 payload_length); + +/** + * @brief Retrieves the payload of a packet + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] payload - pointer to buffer for storing the result + * @param [out] payload_length - size of the retreived payload + * @param [in] hard_copy - Flag : if true (eg. 1), a copy of the payload is + * made into the payload buffer, otherwise (0) the pointer is changed to point + * to the payload offset in the packet. + * @return hICN error code + * + * NOTE: + * - The buffer holding payload is assumed sufficiently large + */ +int hicn_packet_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload, + size_t *payload_size, bool hard_copy); + +/* Header fields manipulation */ + +/** + * @brief Return total length of hicn headers (but signature payload) + * @param [in] pkbuf - hICN packet buffer + * @param [out] header_length - Total length of headers + * @return hICN error code + */ +int hicn_packet_get_header_length_from_format (hicn_packet_format_t format, + size_t *header_length); + +/** + * @brief Sets payload length + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @param [in] payload_length - payload length + * @return hICN error code + */ +int hicn_packet_set_payload_length (const hicn_packet_buffer_t *pkbuf, + const size_t payload_length); + +/** + * @brief Compare two hICN packets + * @param [in] packet_1 - First packet + * @param [in] packet_2 - Second packet + * @return 0 if both packets are considered equal, any other value otherwise. + */ +int hicn_packet_compare (const hicn_packet_buffer_t *pkbuf11, + const hicn_packet_buffer_t *pkbuf22); + +/** + * @brief Retrieve the name of an interest/data packet + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] name - name holding the result + * @return hICN error code + */ +int hicn_packet_get_name (const hicn_packet_buffer_t *pkbuf, + hicn_name_t *name); + +/** + * @brief Sets the name of an interest/data packet + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @param [in] name - name to set into packet + * @return hICN error code + */ +int hicn_packet_set_name (const hicn_packet_buffer_t *pkbuf, + const hicn_name_t *name); + +/** + * @brief Retrieve the locator of an interest / data packet + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] ip_address - retrieved locator + * @return hICN error code + */ +int hicn_packet_get_locator (const hicn_packet_buffer_t *pkbuf, + hicn_ip_address_t *prefix); + +/** + * @brief Sets the locator of an interest / data packet + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @param [out] ip_address - retrieved locator + * @return hICN error code + */ +int hicn_packet_set_locator (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *prefix); + +int hicn_packet_save_header (const hicn_packet_buffer_t *pkbuf, u8 *header, + size_t *header_len, bool copy_ah); + +int hicn_packet_load_header (const hicn_packet_buffer_t *pkbuf, + const u8 *header, size_t header_len); + +int hicn_packet_get_lifetime (const hicn_packet_buffer_t *pkbuf, + u32 *lifetime); +int hicn_packet_set_lifetime (const hicn_packet_buffer_t *pkbuf, u32 lifetime); + +/* Interest */ +int hicn_interest_get_name (const hicn_packet_buffer_t *pkbuf, + hicn_name_t *name); +int hicn_interest_set_name (const hicn_packet_buffer_t *pkbuf, + const hicn_name_t *name); +int hicn_interest_get_locator (const hicn_packet_buffer_t *pkbuf, + hicn_ip_address_t *prefix); +int hicn_interest_set_locator (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *prefix); +int hicn_interest_compare (const hicn_packet_buffer_t *pkbuf11, + const hicn_packet_buffer_t *pkbuf2); +int hicn_interest_set_lifetime (const hicn_packet_buffer_t *pkbuf, + u32 lifetime); +int hicn_interest_get_lifetime (const hicn_packet_buffer_t *pkbuf, + u32 *lifetime); +int hicn_interest_get_header_length (const hicn_packet_buffer_t *pkbuf, + size_t *header_length); +int hicn_interest_get_payload_length (const hicn_packet_buffer_t *pkbuf, + size_t *payload_length); +int hicn_interest_set_payload (const hicn_packet_buffer_t *pkbuf, + const u8 *payload, size_t payload_length); +int hicn_interest_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload, + size_t *payload_size, bool hard_copy); +int hicn_interest_reset_for_hash (hicn_packet_buffer_t *pkbuf); + +/* Data */ + +int hicn_data_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name); +int hicn_data_set_name (const hicn_packet_buffer_t *pkbuf, + const hicn_name_t *name); +int hicn_data_get_locator (const hicn_packet_buffer_t *pkbuf, + hicn_ip_address_t *prefix); +int hicn_data_set_locator (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *prefix); +int hicn_data_compare (const hicn_packet_buffer_t *pkbuf11, + const hicn_packet_buffer_t *pkbuf22); +int hicn_data_get_expiry_time (const hicn_packet_buffer_t *pkbuf, + u32 *expiry_time); +int hicn_data_set_expiry_time (const hicn_packet_buffer_t *pkbuf, + u32 expiry_time); +int hicn_data_get_header_length (const hicn_packet_buffer_t *pkbuf, + size_t *header_length); +int hicn_data_get_payload_length (const hicn_packet_buffer_t *pkbuf, + size_t *payload_length); + +/* Path label */ + +/** + * @brief Returns the path label from a data packet + * @param [in] pkbuf - packet buffer + * @param [in] hdr - packet header + * @param [in] path_label - pointer in which to store the path label value + * @return hICN error code + */ +int hicn_data_get_path_label (const hicn_packet_buffer_t *pkbufdr, + hicn_path_label_t *path_label); + +/** + * @brief Returns the path label from a packet + * @param [in] pkbuf - packet buffer + * @param [in] hdr - packet header + * @param [in] path_label - pointer in which to store the path label value + * @return hICN error code + */ +int hicn_get_path_label (const hicn_packet_buffer_t *pkbufdr, + hicn_path_label_t *path_label); + +int hicn_data_set_path_label (const hicn_packet_buffer_t *pkbuf, + hicn_path_label_t path_label); + +/* Data specific flags */ + +int hicn_packet_get_payload_type (const hicn_packet_buffer_t *pkbuf, + + hicn_payload_type_t *payload_type); +int hicn_packet_set_payload_type (const hicn_packet_buffer_t *pkbuf, + + const hicn_payload_type_t payload_type); + +int hicn_data_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload, + size_t *payload_size, bool hard_copy); +int hicn_data_set_payload (const hicn_packet_buffer_t *pkbuf, + const u8 *payload, size_t payload_length); +int hicn_data_get_payload_type (hicn_payload_type_t *payload_type); +int hicn_data_set_payload_type (hicn_payload_type_t payload_type); +int hicn_data_reset_for_hash (hicn_packet_buffer_t *pkbuf); +int hicn_data_is_last (const hicn_packet_buffer_t *pkbuf, int *is_last); +int hicn_data_set_last (const hicn_packet_buffer_t *pkbuf); + +/* Security */ + +/** + * @brief Retrieves the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] bytes - Retrieved signature size + * @return hICN error code + */ +int hicn_packet_get_signature_size (const hicn_packet_buffer_t *pkbuf, + size_t *bytes); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [in] bytes - Retrieved signature size + * @return hICN error code + */ +int hicn_packet_set_signature_size (const hicn_packet_buffer_t *pkbuf, + size_t bytes); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [in] signature_timestamp - Signature timestamp to set + * @return hICN error code + */ +int hicn_packet_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, + uint64_t signature_timestamp); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] signature_timestamp - Retrieved signature timestamp + * @return hICN error code + */ +int hicn_packet_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, + uint64_t *signature_timestamp); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [in] validation_algorithm - Validation algorithm to set + * @return hICN error code + */ +int hicn_packet_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, + uint8_t validation_algorithm); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] validation_algorithm - Retrieved validation algorithm + * @return hICN error code + */ +int hicn_packet_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, + uint8_t *validation_algorithm); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [in] key_id - Key id to set + * @param [in] key_len - Key length + * @return hICN error code + */ +int hicn_packet_set_key_id (const hicn_packet_buffer_t *pkbuf, uint8_t *key_id, + size_t key_len); + +/** + * @brief Sets the signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] packet - packet header + * @param [out] key_id - Retrieved key id + * @return hICN error code + */ +int hicn_packet_get_key_id (const hicn_packet_buffer_t *pkbuf, + uint8_t **key_id, uint8_t *key_id_length); + +int hicn_packet_get_signature (const hicn_packet_buffer_t *pkbuf, + uint8_t **sign_buf); + +int hicn_packet_get_signature_padding (const hicn_packet_buffer_t *pkbuf, + size_t *bytes); +int hicn_packet_set_signature_padding (const hicn_packet_buffer_t *pkbuf, + size_t bytes); + +/* Checksums */ + +/** + * @brief Update checksums in packet headers + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @return hICN error code + */ +int hicn_packet_compute_checksum (const hicn_packet_buffer_t *pkbuf); + +/** + * @brief compute the checksum of the packet header, adding init_sum to the + * final value + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @param [in] init_sum - value to add to the final checksum + * @return hICN error code + */ +int hicn_packet_compute_header_checksum (const hicn_packet_buffer_t *pkbuf, + u16 init_sum); + +/** + * @brief Verify checksums in packet headers + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] packet - packet header + * @return hICN error code + */ +int hicn_packet_check_integrity_no_payload (const hicn_packet_buffer_t *pkbuf, + u16 init_sum); + +/** + * @brief Returns the packet TTL + * @param [in] pkbuf - hICN packet buffer + * @param [out] hops - Pointer to the variable receiving the TTL value + * @return hICN error code + */ +int hicn_packet_get_ttl (const hicn_packet_buffer_t *pkbuf, u8 *hops); + +/** + * @brief Returns the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] hops - The TTL value to set + * @return hICN error code + */ +int hicn_packet_set_ttl (const hicn_packet_buffer_t *pkbuf, u8 hops); + +/** + * @brief Returns the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [out] port - Pointer to the variable that will receive the port + * number + * @return hICN error code + */ +int hicn_packet_get_src_port (const hicn_packet_buffer_t *pkbuf, u16 *port); + +/** + * @brief Sets the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [out] port - The port number to set + * @return hICN error code + */ +int hicn_packet_set_src_port (const hicn_packet_buffer_t *pkbuf, u16 port); + +/** + * @brief Returns the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [out] port - Pointer to the variable that will receive the port + * number + * @return hICN error code + */ +int hicn_packet_get_dst_port (const hicn_packet_buffer_t *pkbuf, u16 *port); + +/** + * @brief Sets the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [out] port - The port number to set + * @return hICN error code + */ +int hicn_packet_set_dst_port (const hicn_packet_buffer_t *pkbuf, u16 port); + +int hicn_interest_rewrite (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old); + +int hicn_data_rewrite (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, + const hicn_faceid_t face_id, u8 reset_pl); + +#endif /* HICN_PACKET_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/includes/hicn/policy.h b/lib/includes/hicn/policy.h index f39fa9272..50b771537 100644 --- a/lib/includes/hicn/policy.h +++ b/lib/includes/hicn/policy.h @@ -151,7 +151,7 @@ policy_state_t policy_state_from_str (const char *str); /* POLICY TAG STATE */ -typedef struct +typedef struct __attribute__ ((packed, aligned (1))) { policy_state_t state; uint8_t disabled; diff --git a/lib/includes/hicn/protocol/icmprd.h b/lib/includes/hicn/protocol/icmprd.h index 897e7969e..17088c22a 100644 --- a/lib/includes/hicn/protocol/icmprd.h +++ b/lib/includes/hicn/protocol/icmprd.h @@ -33,7 +33,7 @@ typedef struct u8 type; u8 code; u16 csum; - ip4_address_t ip; + ipv4_address_t ip; _ipv4_header_t iph; u8 data[64]; } _icmprd4_header_t; @@ -53,8 +53,8 @@ typedef struct u8 code; u16 csum; u32 res; - ip6_address_t tgt; - ip6_address_t dst; + ipv6_address_t tgt; + ipv6_address_t dst; } _icmprd_header_t; #define ICMPRD_HDRLEN sizeof (_icmprd_header_t) diff --git a/lib/includes/hicn/protocol/ipv4.h b/lib/includes/hicn/protocol/ipv4.h index 44e95c1e3..89435b516 100644 --- a/lib/includes/hicn/protocol/ipv4.h +++ b/lib/includes/hicn/protocol/ipv4.h @@ -54,8 +54,8 @@ typedef struct u8 ttl; u8 protocol; u16 csum; - ip4_address_t saddr; - ip4_address_t daddr; + ipv4_address_t saddr; + ipv4_address_t daddr; } _ipv4_header_t; #define ipv4_header_bytes(ipv4_header) \ @@ -72,8 +72,8 @@ static_assert (EXPECTED_IPV4_HDRLEN == IPV4_HDRLEN, typedef struct { - ip4_address_t ip_src; - ip4_address_t ip_dst; + ipv4_address_t ip_src; + ipv4_address_t ip_dst; u8 zero; u8 protocol; u16 size; diff --git a/lib/includes/hicn/protocol/ipv6.h b/lib/includes/hicn/protocol/ipv6.h index 86301e7d1..6e8e30af3 100644 --- a/lib/includes/hicn/protocol/ipv6.h +++ b/lib/includes/hicn/protocol/ipv6.h @@ -42,8 +42,8 @@ typedef struct u8 vfc; /* 4 bits version, top 4 bits class */ }; #endif - ip6_address_t saddr; /* source address */ - ip6_address_t daddr; /* destination address */ + ipv6_address_t saddr; /* source address */ + ipv6_address_t daddr; /* destination address */ } _ipv6_header_t; #define IPV6_HDRLEN sizeof (_ipv6_header_t) @@ -57,8 +57,8 @@ static_assert (EXPECTED_IPV6_HDRLEN == IPV6_HDRLEN, typedef struct { - ip6_address_t ip_src; - ip6_address_t ip_dst; + ipv6_address_t ip_src; + ipv6_address_t ip_dst; u32 size; u16 zeros; u8 zero; diff --git a/lib/includes/hicn/protocol/new.h b/lib/includes/hicn/protocol/new.h index 47f7758d2..e688bef21 100644 --- a/lib/includes/hicn/protocol/new.h +++ b/lib/includes/hicn/protocol/new.h @@ -34,7 +34,7 @@ typedef struct u8 flags; u16 payload_length; u32 lifetime; - ip_address_t prefix; + hicn_ip_address_t prefix; u32 suffix; u32 path_label; } _new_header_t; diff --git a/lib/includes/hicn/util/bitmap.h b/lib/includes/hicn/util/bitmap.h index 11eb7870b..15d47ac61 100644 --- a/lib/includes/hicn/util/bitmap.h +++ b/lib/includes/hicn/util/bitmap.h @@ -24,17 +24,26 @@ #define UTIL_BITMAP_H #include <assert.h> +#include <stdio.h> #include <string.h> #include <sys/param.h> // MIN, MAX -#include <hicn/util/log.h> - #include <hicn/common.h> #include <hicn/util/vector.h> -typedef uint_fast32_t bitmap_t; +typedef hicn_uword bitmap_t; + +#define WORD_WIDTH (sizeof (bitmap_t) * 8) +#define WORD_WIDTH (sizeof (bitmap_t) * 8) #define BITMAP_WIDTH(bitmap) (sizeof ((bitmap)[0]) * 8) +#define BITMAP_INVALID_INDEX ((uint32_t) (~0)) + +static inline int +get_lowest_set_bit_index (hicn_uword w) +{ + return hicn_uword_bits > 32 ? __builtin_ctzll (w) : __builtin_ctz (w); +} /** * @brief Allocate and initialize a bitmap @@ -79,13 +88,27 @@ bitmap_ensure_pos (bitmap_t **bitmap, off_t pos) * @param[in] i The bit position. */ static inline int -bitmap_get (const bitmap_t *bitmap, off_t i) +_bitmap_get (const bitmap_t *bitmap, off_t i) { size_t offset = i / BITMAP_WIDTH (bitmap); assert (offset < bitmap_get_alloc_size (bitmap)); size_t pos = i % BITMAP_WIDTH (bitmap); - size_t shift = BITMAP_WIDTH (bitmap) - pos - 1; - return (bitmap[offset] >> shift) & 1; + return (bitmap[offset] >> pos) & 1; +} + +/** + * @brief Retrieve the state of the i-th bit in the bitmap. + * Does not sanity check the position. + * + * @param[in] bitmap The bitmap to access. + * @param[in] i The bit position. + */ +static inline int +_bitmap_get_no_check (const bitmap_t *bitmap, off_t i) +{ + size_t offset = i / BITMAP_WIDTH (bitmap); + size_t pos = i % BITMAP_WIDTH (bitmap); + return (bitmap[offset] >> pos) & 1; } /* @@ -96,8 +119,13 @@ bitmap_get (const bitmap_t *bitmap, off_t i) * * @return bool */ -#define bitmap_is_set(bitmap, i) (bitmap_get ((bitmap), (i)) == 1) -#define bitmap_is_unset(bitmap, i) (bitmap_get ((bitmap), (i)) == 0) +#define bitmap_is_set(bitmap, i) (_bitmap_get ((bitmap), (i)) == 1) +#define bitmap_is_unset(bitmap, i) (_bitmap_get ((bitmap), (i)) == 0) + +#define bitmap_is_set_no_check(bitmap, i) \ + (_bitmap_get_no_check ((bitmap), (i)) == 1) +#define bitmap_is_unset_no_check(bitmap, i) \ + (_bitmap_get_no_check ((bitmap), (i)) == 0) /* * @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap. @@ -107,7 +135,9 @@ bitmap_get (const bitmap_t *bitmap, off_t i) * * @return bool */ -#define bitmap_set(bitmap, i) _bitmap_set ((bitmap_t **) &bitmap, i) +#define bitmap_set(bitmap, i) _bitmap_set ((bitmap_t **) &bitmap, i, 1) +#define bitmap_set_no_check(bitmap, i) \ + _bitmap_set ((bitmap_t **) &bitmap, i, 0) /* * @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap @@ -119,29 +149,30 @@ bitmap_get (const bitmap_t *bitmap, off_t i) * @return bool */ static inline int -_bitmap_set (bitmap_t **bitmap_ptr, off_t i) +_bitmap_set (bitmap_t **bitmap_ptr, off_t i, int check) { - if (bitmap_ensure_pos (bitmap_ptr, i) < 0) + if (check && bitmap_ensure_pos (bitmap_ptr, i) < 0) return -1; bitmap_t *bitmap = *bitmap_ptr; size_t offset = i / BITMAP_WIDTH (bitmap); size_t pos = i % BITMAP_WIDTH (bitmap); - size_t shift = BITMAP_WIDTH (bitmap) - pos - 1; - bitmap[offset] |= (bitmap_t) 1 << shift; + bitmap[offset] |= (bitmap_t) 1 << pos; return 0; } +#define bitmap_unset(bitmap, i) _bitmap_unset (bitmap, i, 1) +#define bitmap_unset_no_check(bitmap, i) _bitmap_unset (bitmap, i, 0) + static inline int -bitmap_unset (bitmap_t *bitmap, off_t i) +_bitmap_unset (bitmap_t *bitmap, off_t i, int check) { - if (bitmap_ensure_pos (&bitmap, i) < 0) + if (check && bitmap_ensure_pos (&bitmap, i) < 0) return -1; size_t offset = i / BITMAP_WIDTH (bitmap); size_t pos = i % BITMAP_WIDTH (bitmap); - size_t shift = BITMAP_WIDTH (bitmap) - pos - 1; - bitmap[offset] &= ~(1ul << shift); + bitmap[offset] &= ~(1ul << pos); return 0; } @@ -201,7 +232,6 @@ bitmap_set_range (bitmap_t *bitmap, off_t from, off_t to) return 0; END: - ERROR ("Error setting bitmap range\n"); return -1; } @@ -209,4 +239,88 @@ END: #define bitmap_free(bitmap) vector_free (bitmap) +static inline hicn_uword +bitmap_next_set_no_check (const bitmap_t *bitmap, hicn_uword i, size_t length) +{ + hicn_uword pos = i / WORD_WIDTH; + hicn_uword offset = i % WORD_WIDTH; + hicn_uword tmp; + hicn_uword mask = ~((1ULL << offset) - 1); + + if (pos < length) + { + // This will zeroes all bits < i + tmp = bitmap[pos] & mask; + if (tmp) + return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH; + + for (pos += 1; pos < length; pos++) + { + tmp = bitmap[pos]; + if (tmp) + return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH; + } + } + + return BITMAP_INVALID_INDEX; +} + +static inline hicn_uword +bitmap_next_set (const bitmap_t *bitmap, hicn_uword i) +{ + return bitmap_next_set_no_check (bitmap, i, vector_get_alloc_size (bitmap)); +} + +static inline hicn_uword +bitmap_next_unset_no_check (const bitmap_t *bitmap, hicn_uword i, + size_t length) +{ + hicn_uword pos = i / WORD_WIDTH; + hicn_uword offset = i % WORD_WIDTH; + hicn_uword tmp; + hicn_uword mask = ~((1ULL << offset) - 1); + + if (pos < length) + { + // This will zeroes all bits < i + tmp = ~bitmap[pos] & mask; + if (tmp) + return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH; + + for (pos += 1; pos < length; pos++) + { + tmp = ~bitmap[pos]; + if (tmp) + return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH; + } + } + return BITMAP_INVALID_INDEX; +} + +static inline hicn_uword +bitmap_next_unset (const bitmap_t *bitmap, hicn_uword i) +{ + return bitmap_next_unset_no_check (bitmap, i, + vector_get_alloc_size (bitmap)); +} + +#define bitmap_first_set(bitmap) bitmap_next_set (bitmap, 0) +#define bitmap_first_set_no_check(bitmap, size) \ + bitmap_next_set_no_checks (bitmap, 0, size) + +#define bitmap_first_unset(bitmap) bitmap_next_unset (bitmap, 0) +#define bitmap_first_unset_no_check(bitmap, size) \ + bitmap_next_unset_no_checks (bitmap, 0, size) + +static inline void +bitmap_print (const bitmap_t *bitmap, size_t n_words) +{ + for (size_t word = 0; word < n_words; word++) + { + for (int bit = sizeof (hicn_uword) - 1; bit >= 0; bit--) + (bitmap_is_set_no_check (&bitmap[word], bit)) ? printf ("1") : + printf ("0"); + } +} + #endif /* UTIL_BITMAP_H */ diff --git a/lib/includes/hicn/util/hash.h b/lib/includes/hicn/util/hash.h index ded8fc370..8dbe0d680 100644 --- a/lib/includes/hicn/util/hash.h +++ b/lib/includes/hicn/util/hash.h @@ -28,6 +28,7 @@ #define UTIL_HASH_H #include <stdint.h> +#include <stddef.h> // size_t #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ __BYTE_ORDER == __LITTLE_ENDIAN) || \ diff --git a/lib/includes/hicn/util/ip_address.h b/lib/includes/hicn/util/ip_address.h index 89a4c11e0..55d5f5fc3 100644 --- a/lib/includes/hicn/util/ip_address.h +++ b/lib/includes/hicn/util/ip_address.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -32,10 +32,11 @@ #endif #include <errno.h> +#include <assert.h> #ifndef _WIN32 #include <netinet/in.h> // struct sockadd -#include <arpa/inet.h> -#include <netdb.h> // struct addrinfo +#include <arpa/inet.h> // inet_ntop +#include <netdb.h> // struct addrinfo #endif #include <stdbool.h> #include <stdlib.h> @@ -61,11 +62,10 @@ #endif //#define INET_MAX_ADDRSTRLEN INET6_ADDRSTRLEN -#define IP_MAX_ADDR_LEN IPV6_ADDR_LEN +#define IP_ADDRESS_MAX_LEN IPV6_ADDR_LEN #define DUMMY_PORT 1234 -#ifndef HICN_VPP_PLUGIN typedef union { struct in_addr as_inaddr; @@ -73,9 +73,11 @@ typedef union u8 as_u8[4]; u16 as_u16[2]; u32 as_u32; -} ip4_address_t; +} ipv4_address_t; -typedef union +static_assert (sizeof (ipv4_address_t) == 4, ""); + +typedef union __attribute__ ((__packed__)) { struct in6_addr as_in6addr; u8 buffer[16]; @@ -83,16 +85,24 @@ typedef union u16 as_u16[8]; u32 as_u32[4]; u64 as_u64[2]; -} ip6_address_t; +} ipv6_address_t; + +static_assert (sizeof (ipv6_address_t) == 16, ""); + +#ifdef HICN_VPP_PLUGIN +#include <vnet/ip/ip46_address.h> +static_assert (sizeof (ipv4_address_t) == sizeof (ip4_address_t), ""); +static_assert (sizeof (ipv6_address_t) == sizeof (ip6_address_t), ""); +#endif typedef union { struct { u32 pad[3]; - ip4_address_t v4; + ipv4_address_t v4; }; - ip6_address_t v6; + ipv6_address_t v6; #if 0 /* removed as prone to error due to IPv4 padding */ u8 buffer[IP_MAX_ADDR_LEN]; u8 as_u8[IP_MAX_ADDR_LEN]; @@ -100,28 +110,14 @@ typedef union u32 as_u32[IP_MAX_ADDR_LEN >> 2]; u64 as_u64[IP_MAX_ADDR_LEN >> 3]; #endif -} ip_address_t; - -#else - -#include <vnet/ip/ip4_packet.h> // ip4_address_t -#include <vnet/ip/ip6_packet.h> // ip6_address_t - -#if __GNUC__ >= 9 -#pragma GCC diagnostic ignored "-Waddress-of-packed-member" -#endif - -#include <vnet/ip/ip46_address.h> - -#if __GNUC__ >= 9 -#pragma GCC diagnostic pop -#endif - -typedef ip46_address_t ip_address_t; - +#ifdef HICN_VPP_PLUGIN + ip46_address_t as_ip46; #endif /* HICN_VPP_PLUGIN */ +} hicn_ip_address_t; + +static_assert (sizeof (hicn_ip_address_t) == 16, ""); -#define ip_address_is_v4(ip) \ +#define hicn_ip_address_is_v4(ip) \ (((ip)->pad[0] | (ip)->pad[1] | (ip)->pad[2]) == 0) #define MAXSZ_IP4_ADDRESS_ INET_ADDRSTRLEN - 1 @@ -131,24 +127,26 @@ typedef ip46_address_t ip_address_t; #define MAXSZ_IP6_ADDRESS MAXSZ_IP6_ADDRESS_ + 1 #define MAXSZ_IP_ADDRESS MAXSZ_IP_ADDRESS_ + 1 +#define IP_ADDRESS_V4_OFFSET_LEN 12 + typedef struct { int family; - ip_address_t address; + hicn_ip_address_t address; u8 len; -} ip_prefix_t; +} hicn_ip_prefix_t; #define MAXSZ_IP_PREFIX_ MAXSZ_IP_ADDRESS_ + 1 + 3 #define MAXSZ_IP_PREFIX MAXSZ_IP_PREFIX_ + 1 -extern const ip_address_t IPV4_LOOPBACK; -extern const ip_address_t IPV6_LOOPBACK; -extern const ip_address_t IPV4_ANY; -extern const ip_address_t IPV6_ANY; +extern const hicn_ip_address_t IPV4_LOOPBACK; +extern const hicn_ip_address_t IPV6_LOOPBACK; +extern const hicn_ip_address_t IPV4_ANY; +extern const hicn_ip_address_t IPV6_ANY; -extern const ip4_address_t IP4_ADDRESS_EMPTY; -extern const ip6_address_t IP6_ADDRESS_EMPTY; -extern const ip_address_t IP_ADDRESS_EMPTY; +extern const ipv4_address_t IP4_ADDRESS_EMPTY; +extern const ipv6_address_t IP6_ADDRESS_EMPTY; +extern const hicn_ip_address_t IP_ADDRESS_EMPTY; #define IP_ANY(family) (family == AF_INET) ? IPV4_ANY : IPV6_ANY @@ -161,32 +159,52 @@ extern const ip_address_t IP_ADDRESS_EMPTY; #define IS_VALID_FAMILY(x) ((x == AF_INET) || (x == AF_INET6)) /* IP address */ - -int ip_address_get_family (const char *ip_address); -int ip_address_len (int family); -const u8 *ip_address_get_buffer (const ip_address_t *ip_address, int family); -int ip_address_ntop (const ip_address_t *ip_address, char *dst, - const size_t len, int family); -int ip_address_pton (const char *ip_address_str, ip_address_t *ip_address); -int ip_address_snprintf (char *s, size_t size, const ip_address_t *ip_address, - int family); -int ip_address_to_sockaddr (const ip_address_t *ip_address, - struct sockaddr *sa, int family); -int ip_address_cmp (const ip_address_t *ip1, const ip_address_t *ip2, - int family); -int ip_address_empty (const ip_address_t *ip); +int hicn_ip_address_get_family (const hicn_ip_address_t *address); +int hicn_ip_address_str_get_family (const char *ip_address); +int hicn_ip_address_len (int family); +int hicn_ip_address_get_len (const hicn_ip_address_t *ip_address); + +int hicn_ip_address_get_len_bits (const hicn_ip_address_t *ip_address); +const u8 *hicn_ip_address_get_buffer (const hicn_ip_address_t *ip_address, + int family); +int hicn_ip_address_ntop (const hicn_ip_address_t *ip_address, char *dst, + const size_t len, int family); +int hicn_ip_address_pton (const char *ip_address_str, + hicn_ip_address_t *ip_address); +int hicn_ip_address_snprintf (char *s, size_t size, + const hicn_ip_address_t *ip_address); +int hicn_ip_address_to_sockaddr (const hicn_ip_address_t *ip_address, + struct sockaddr *sa, int family); +int hicn_ip_address_cmp (const hicn_ip_address_t *ip1, + const hicn_ip_address_t *ip2); +bool hicn_ip_address_equals (const hicn_ip_address_t *ip1, + const hicn_ip_address_t *ip2); +int hicn_ip_address_empty (const hicn_ip_address_t *ip); + +uint8_t hicn_ip_address_get_bit (const hicn_ip_address_t *address, + uint8_t pos); + +bool hicn_ip_address_match_family (const hicn_ip_address_t *address, + int family); + +uint32_t hicn_ip_address_get_hash (const hicn_ip_address_t *address); /* Prefix */ -int ip_prefix_pton (const char *ip_address_str, ip_prefix_t *ip_prefix); -int ip_prefix_ntop_short (const ip_prefix_t *ip_prefix, char *dst, - size_t size); -int ip_prefix_ntop (const ip_prefix_t *ip_prefix, char *dst, size_t size); -int ip_prefix_snprintf (char *s, size_t size, const ip_prefix_t *prefix); -int ip_prefix_len (const ip_prefix_t *prefix); -bool ip_prefix_empty (const ip_prefix_t *prefix); -int ip_prefix_to_sockaddr (const ip_prefix_t *prefix, struct sockaddr *sa); -int ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2); +int hicn_ip_prefix_pton (const char *ip_address_str, + hicn_ip_prefix_t *hicn_ip_prefix); +int hicn_ip_prefix_ntop_short (const hicn_ip_prefix_t *hicn_ip_prefix, + char *dst, size_t size); +int hicn_ip_prefix_ntop (const hicn_ip_prefix_t *hicn_ip_prefix, char *dst, + size_t size); +int hicn_ip_prefix_snprintf (char *s, size_t size, + const hicn_ip_prefix_t *prefix); +int hicn_ip_prefix_len (const hicn_ip_prefix_t *prefix); +bool hicn_ip_prefix_empty (const hicn_ip_prefix_t *prefix); +int hicn_ip_prefix_to_sockaddr (const hicn_ip_prefix_t *prefix, + struct sockaddr *sa); +int hicn_ip_prefix_cmp (const hicn_ip_prefix_t *prefix1, + const hicn_ip_prefix_t *prefix2); /* URL */ @@ -200,7 +218,7 @@ int ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2); #define MAXSZ_URL6 MAXSZ_URL6_ + NULLTERM #define MAXSZ_URL MAXSZ_URL_ + NULLTERM -int url_snprintf (char *s, size_t size, int family, - const ip_address_t *ip_address, u16 port); +int url_snprintf (char *s, size_t size, const hicn_ip_address_t *ip_address, + u16 port); #endif /* UTIL_IP_ADDRESS_H */ diff --git a/lib/includes/hicn/util/pool.h b/lib/includes/hicn/util/pool.h index 7488e08fd..b8acadc44 100644 --- a/lib/includes/hicn/util/pool.h +++ b/lib/includes/hicn/util/pool.h @@ -234,6 +234,26 @@ bool _pool_validate_id (void **pool_ptr, off_t id); } \ while (0) +#define pool_enumerate_typed(pool, i, TYPE, ELTP, BODY) \ + do \ + { \ + pool_hdr_t *_pool_var (ph) = pool_hdr (pool); \ + bitmap_t *_pool_var (fb) = _pool_var (ph)->free_bitmap; \ + TYPE ELTP = NULL; \ + for ((i) = 0; (i) < _pool_var (ph)->alloc_size; (i)++) \ + { \ + if (bitmap_is_set (_pool_var (fb), (i))) \ + continue; \ + ELTP = (pool) + (i); \ + do \ + { \ + BODY; \ + } \ + while (0); \ + } \ + } \ + while (0) + /** * @brief Iterate over elements in a pool. * @@ -256,6 +276,14 @@ bool _pool_validate_id (void **pool_ptr, off_t id); #define pool_get_alloc_size(pool) pool_hdr (pool)->alloc_size +#define pool_foreach_typed(pool, TYPE, ELTP, BODY) \ + do \ + { \ + unsigned _pool_var (i); \ + pool_enumerate_typed ((pool), _pool_var (i), TYPE, ELTP, BODY); \ + } \ + while (0) + #ifdef WITH_TESTS #define pool_get_free_indices(pool) pool_hdr (pool)->free_indices #define pool_get_free_bitmap(pool) pool_hdr (pool)->free_bitmap diff --git a/lib/includes/hicn/util/sstrncpy.h b/lib/includes/hicn/util/sstrncpy.h index b316201be..81427be6b 100644 --- a/lib/includes/hicn/util/sstrncpy.h +++ b/lib/includes/hicn/util/sstrncpy.h @@ -16,7 +16,10 @@ #ifndef UTIL_SSTRNCPY_H #define UTIL_SSTRNCPY_H +#ifndef __STDC_WANT_LIB_EXT1__ #define __STDC_WANT_LIB_EXT1__ 1 +#endif + #include <string.h> #ifdef __STDC_LIB_EXT1__ @@ -30,6 +33,9 @@ typedef int errno_t; #define EOK 0 +#ifndef HICN_VPP_PLUGIN +/* This function is already defined in vppinfra/string.h */ + /** * @brief This function assures a null byte at the end of the buffer. */ @@ -63,6 +69,7 @@ strnlen_s (const char *s, size_t maxlen) return strnlen (s, maxlen); } +#endif /* HICN_VPP_PLUGIN */ #endif /* __STDC_LIB_EXT1__ */ #endif /* UTIL_SSTRNCPY_H */ diff --git a/lib/includes/hicn/util/types.h b/lib/includes/hicn/util/types.h index 50c5362d3..c9cc878cf 100644 --- a/lib/includes/hicn/util/types.h +++ b/lib/includes/hicn/util/types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -19,11 +19,46 @@ #include <hicn/util/windows/windows_Utils.h> #endif +/* Standard types. */ +#include <stdint.h> + typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef double f64; +typedef float f32; + +/* Architecture-dependent uword size */ +#if INTPTR_MAX == INT64_MAX +#define hicn_log2_uword_bits 6 +#elif INTPTR_MAX == INT32_MAX +#define hicn_log2_uword_bits 5 +#else +#error "Impossible to detect architecture" +#endif + +#define hicn_uword_bits (1 << hicn_log2_uword_bits) + +/* Word types. */ +#if hicn_uword_bits == 64 +/* 64 bit word machines. */ +typedef u64 hicn_uword; +#else +/* 32 bit word machines. */ +typedef u32 hicn_uword; +#endif + +typedef hicn_uword hicn_ip_csum_t; + +#define hicn_uword_bits (1 << hicn_log2_uword_bits) + /* Helper for avoiding warnings about type-punning */ #define UNION_CAST(x, destType) \ (((union { \ @@ -32,12 +67,15 @@ typedef uint64_t u64; }) x) \ .b) -// typedef unsigned int hash_t; - typedef int (*cmp_t) (const void *, const void *); /* Enums */ #define IS_VALID_ENUM_TYPE(NAME, x) ((x > NAME##_UNDEFINED) && (x < NAME##_N)) +/* Float */ + +uint32_t htonf (float f); +float ntohf (uint32_t i); + #endif /* UTIL_TYPES */ diff --git a/lib/includes/hicn/util/vector.h b/lib/includes/hicn/util/vector.h index 46f195c6d..e693df9e3 100644 --- a/lib/includes/hicn/util/vector.h +++ b/lib/includes/hicn/util/vector.h @@ -209,7 +209,7 @@ static inline int _vector_get (void *vector, off_t pos, size_t elt_size, void *elt) { vector_hdr_t *vh = vector_hdr (vector); - if (pos >= vh->alloc_size) + if ((size_t) pos >= vh->alloc_size) return -1; memcpy (elt, (uint8_t *) vector + pos * elt_size, elt_size); @@ -228,7 +228,7 @@ _vector_get (void *vector, off_t pos, size_t elt_size, void *elt) static inline bool _vector_contains (void *vector, size_t elt_size, void *elt) { - for (int i = 0; i < vector_hdr (vector)->cur_size; i++) + for (size_t i = 0; i < vector_hdr (vector)->cur_size; i++) { if (memcmp ((uint8_t *) vector + i * elt_size, elt, elt_size) == 0) return true; @@ -251,7 +251,7 @@ static inline int _vector_remove_at (void **vector_ptr, size_t elt_size, off_t pos) { vector_hdr_t *vh = vector_hdr (*vector_ptr); - if (pos >= vh->cur_size) + if ((size_t) pos >= vh->cur_size) return -1; // Shift backward by one position all the elements after the one specified @@ -342,7 +342,7 @@ _vector_remove_at (void **vector_ptr, size_t elt_size, off_t pos) #define vector_at(vector, pos) \ ({ \ - assert (pos < vector_hdr (vector)->cur_size); \ + assert ((size_t) pos < vector_hdr (vector)->cur_size); \ (vector)[(pos)]; \ }) diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt index 8e81aa442..10c39fae2 100644 --- a/lib/src/CMakeLists.txt +++ b/lib/src/CMakeLists.txt @@ -15,13 +15,14 @@ # Source and Header files ############################################################## list(APPEND LIBHICN_SOURCE_FILES + base.c common.c - compat.c error.c face.c mapme.c name.c ops.c + packet.c policy.c strategy.c protocol/ah.c @@ -35,6 +36,7 @@ list(APPEND LIBHICN_SOURCE_FILES util/log.c util/pool.c util/ring.c + util/types.c util/vector.c ) @@ -72,6 +74,7 @@ endif() ############################################################## set(COMPILER_OPTIONS ${DEFAULT_COMPILER_OPTIONS} + PRIVATE "-Wno-address-of-packed-member" ) diff --git a/lib/src/base.c b/lib/src/base.c new file mode 100644 index 000000000..a15d55938 --- /dev/null +++ b/lib/src/base.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file base.c + * @brief Implementation of base hICN definitions. + */ + +#include <hicn/base.h> +#include "ops.h" + +const char *_hicn_packet_type_str[] = { +#define _(x) [HICN_PACKET_TYPE_##x] = #x, + foreach_packet_type +#undef _ +}; + +int +hicn_packet_format_snprintf (char *s, size_t size, hicn_packet_format_t format) +{ + char *cur = s; + int rc; + for (unsigned i = 0; i < 4; i++) + { + if (i > 0) + { + rc = snprintf (cur, size - (cur - s), " %s ", "/"); + if (rc < 0 || rc >= size - (cur - s)) + return rc; + cur += rc; + } + + rc = snprintf (cur, size - (cur - s), "%s", + hicn_ops_vft[format.as_u8[i]]->name); + if (rc < 0 || rc >= size - (cur - s)) + return rc; + cur += rc; + } + return (int) (cur - s); +} diff --git a/lib/src/compat.c b/lib/src/compat.c deleted file mode 100644 index cb771dbdd..000000000 --- a/lib/src/compat.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file compat.c - * @brief Implementation of the compatibility layer. - */ -#ifndef _WIN32 -#include <netinet/in.h> -#endif -#include <string.h> // memset -#include <stddef.h> // offsetof - -#include <hicn/common.h> -#include <hicn/compat.h> -#include <hicn/error.h> -#include <hicn/header.h> -#include <hicn/name.h> -#include <hicn/ops.h> - -#define member_size(type, member) sizeof (((type *) 0)->member) -#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a))) - -#define HICN_NAME_COMPONENT_SIZE 2 - -int -hicn_packet_get_format (const hicn_header_t *h, hicn_format_t *format) -{ - *format = HF_UNSPEC; - - switch (HICN_IP_VERSION (h)) - { - case 4: - switch (h->v4.ip.protocol) - { - case IPPROTO_TCP: - if (h->v4.tcp.flags & AH_FLAG) - *format = HF_INET_TCP_AH; - else - *format = HF_INET_TCP; - break; - case IPPROTO_UDP: - if (h->v4.newhdr.flags & HICN_NEW_FLAG_SIG) - *format = HF_INET_UDP_AH; - else - *format = HF_INET_UDP; - break; - case IPPROTO_ICMP: - *format = HF_INET_ICMP; - break; - default: - return HICN_LIB_ERROR_NOT_HICN; - } - break; - case 6: - switch (h->v6.ip.nxt) - { - case IPPROTO_TCP: - if (h->v6.tcp.flags & AH_FLAG) - *format = HF_INET6_TCP_AH; - else - *format = HF_INET6_TCP; - break; - case IPPROTO_UDP: - if (h->v6.newhdr.flags & HICN_NEW_FLAG_SIG) - *format = HF_INET6_UDP_AH; - else - *format = HF_INET6_UDP; - break; - case IPPROTO_ICMPV6: - *format = HF_INET6_ICMP; - break; - default: - return HICN_LIB_ERROR_NOT_HICN; - } - break; - case 9: - { - uint8_t ah = (HICN_NEW_FLAG_SIG & h->protocol.newhdr.flags); - *format = HF_NEW_AH * ah + (1 - ah) * HF_NEW; - break; - } - default: - return HICN_LIB_ERROR_NOT_HICN; - } - - return HICN_LIB_ERROR_NONE; -} - -/** - * @brief Convert (former) hICN format into (newer) hICN type - * @param [in] format - hICN format - * @return hICN type, all zero'ed if type is unknown - */ -hicn_type_t -hicn_format_to_type (hicn_format_t format) -{ - switch (format) - { - case HF_INET_TCP: - return HICN_TYPE_IPV4_TCP; - case HF_INET_UDP: - return HICN_TYPE_IPV4_UDP; - case HF_INET6_TCP: - return HICN_TYPE_IPV6_TCP; - case HF_INET6_UDP: - return HICN_TYPE_IPV6_UDP; - case HF_INET_ICMP: - return HICN_TYPE_IPV4_ICMP; - case HF_INET6_ICMP: - return HICN_TYPE_IPV6_ICMP; - case HF_NEW: - return HICN_TYPE_NEW; - case HF_INET_TCP_AH: - return HICN_TYPE_IPV4_TCP_AH; - case HF_INET_UDP_AH: - return HICN_TYPE_IPV4_UDP_AH; - case HF_INET6_TCP_AH: - return HICN_TYPE_IPV6_TCP_AH; - case HF_INET6_UDP_AH: - return HICN_TYPE_IPV6_UDP_AH; - case HF_INET_ICMP_AH: - return HICN_TYPE_IPV4_ICMP_AH; - case HF_INET6_ICMP_AH: - return HICN_TYPE_IPV6_ICMP_AH; - case HF_NEW_AH: - return HICN_TYPE_NEW_AH; - default: - break; - } - return HICN_TYPE_NONE; -} - -/** - * @brief Parse hICN header and return hICN type - * @param [in] h - hICN header - * @param [out] format - hICN type - * @return hICN error code - * - * This function is used to wrap old API calls to new ones - */ -hicn_type_t -hicn_header_to_type (const hicn_header_t *h) -{ - hicn_format_t format; - hicn_packet_get_format (h, &format); - return hicn_format_to_type (format); -} - -int -hicn_packet_init_header (hicn_format_t format, hicn_header_t *packet) -{ - hicn_type_t type = hicn_format_to_type (format); - - if (hicn_type_is_none (type)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - return hicn_ops_vft[type.l1]->init_packet_header (type, &packet->protocol); -} - -int -hicn_packet_compute_checksum (hicn_format_t format, hicn_header_t *h) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, 0, ~0); -} - -int -hicn_packet_compute_header_checksum (hicn_format_t format, hicn_header_t *h, - u16 init_sum) -{ - hicn_type_t type = hicn_format_to_type (format); - /* payload_length == 0: ignore payload */ - return hicn_ops_vft[type.l1]->update_checksums (type, &h->protocol, init_sum, - 0); -} - -int -hicn_packet_check_integrity_no_payload (hicn_format_t format, hicn_header_t *h, - u16 init_sum) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->verify_checksums (type, &h->protocol, init_sum, - 0); -} - -int -hicn_packet_get_header_length_from_format (hicn_format_t format, - size_t *header_length) -{ - *header_length = _is_ipv4 (format) * IPV4_HDRLEN; - *header_length += _is_ipv6 (format) * IPV6_HDRLEN; - *header_length += _is_icmp (format) * ICMP_HDRLEN; - *header_length += _is_tcp (format) * TCP_HDRLEN; - *header_length += _is_udp (format) * UDP_HDRLEN; - *header_length += _is_cmpr (format) * NEW_HDRLEN; - *header_length += _is_ah (format) * AH_HDRLEN; - - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_get_header_length (hicn_format_t format, const hicn_header_t *h, - size_t *header_length) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol, - header_length); -} - -int -hicn_packet_get_payload_length (hicn_format_t format, const hicn_header_t *h, - size_t *payload_length) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol, - payload_length); -} - -int -hicn_packet_set_payload_length (hicn_format_t format, hicn_header_t *h, - const size_t payload_length) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_payload_length (type, &h->protocol, - payload_length); -} - -int -hicn_packet_compare (const hicn_header_t *packet1, - const hicn_header_t *packet2) -{ - hicn_type_t type1 = hicn_header_to_type (packet1); - hicn_type_t type2 = hicn_header_to_type (packet2); - - size_t len1, len2; - int rc; - - if (type1.as_u32 != type2.as_u32) - return HICN_LIB_ERROR_UNEXPECTED; - - rc = hicn_ops_vft[type1.l1]->get_length (type1, &packet1->protocol, &len1); - if (PREDICT_FALSE (rc < 0)) - return HICN_LIB_ERROR_UNEXPECTED; - - rc = hicn_ops_vft[type2.l1]->get_length (type2, &packet2->protocol, &len2); - if (PREDICT_FALSE (rc < 0)) - return HICN_LIB_ERROR_UNEXPECTED; - - if (len1 != len2) - return HICN_LIB_ERROR_UNEXPECTED; - - return memcmp ((u8 *) packet1, (u8 *) packet2, len1); -} - -int -hicn_packet_get_name (hicn_format_t format, const hicn_header_t *h, - hicn_name_t *name, u8 is_interest) -{ - hicn_type_t type = hicn_format_to_type (format); - - if (is_interest) - return hicn_ops_vft[type.l1]->get_interest_name (type, &h->protocol, name); - else - return hicn_ops_vft[type.l1]->get_data_name (type, &h->protocol, name); -} - -int -hicn_packet_set_name (hicn_format_t format, hicn_header_t *h, - const hicn_name_t *name, u8 is_interest) -{ - hicn_type_t type = hicn_format_to_type (format); - - if (is_interest) - return hicn_ops_vft[type.l1]->set_interest_name (type, &h->protocol, name); - else - return hicn_ops_vft[type.l1]->set_data_name (type, &h->protocol, name); -} - -int -hicn_packet_set_payload (hicn_format_t format, hicn_header_t *h, - const u8 *payload, u16 payload_length) -{ - hicn_type_t type = hicn_format_to_type (format); - size_t header_length; - int rc; - - rc = hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol, - &header_length); - if (rc < 0) - return rc; - - memcpy ((u8 *) h + header_length, payload, payload_length); - - return hicn_ops_vft[type.l1]->set_payload_length (type, &h->protocol, - payload_length); -} - -int -hicn_packet_get_payload (hicn_format_t format, const hicn_header_t *h, - u8 **payload, size_t *payload_size, bool hard_copy) -{ - size_t header_length, payload_length; - int rc; - hicn_type_t type = hicn_format_to_type (format); - - rc = hicn_ops_vft[type.l1]->get_header_length (type, &h->protocol, - &header_length); - if (rc < 0) - return rc; - - rc = hicn_ops_vft[type.l1]->get_payload_length (type, &h->protocol, - &payload_length); - if (rc < 0) - return rc; - - if (hard_copy) - { - memcpy (payload, (u8 *) h + header_length, payload_length); - } - else - { - *payload = (u8 *) h + header_length; - } - - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_get_locator (hicn_format_t format, const hicn_header_t *h, - ip_address_t *address, bool is_interest) -{ - hicn_type_t type = hicn_format_to_type (format); - if (is_interest) - return hicn_ops_vft[type.l1]->get_interest_locator (type, &h->protocol, - address); - else - return hicn_ops_vft[type.l1]->get_data_locator (type, &h->protocol, - address); -} - -int -hicn_packet_set_locator (hicn_format_t format, hicn_header_t *h, - const ip_address_t *address, bool is_interest) -{ - hicn_type_t type = hicn_format_to_type (format); - if (is_interest) - return hicn_ops_vft[type.l1]->set_interest_locator (type, &h->protocol, - address); - else - return hicn_ops_vft[type.l1]->set_data_locator (type, &h->protocol, - address); -} - -int -hicn_packet_get_signature_size (hicn_format_t format, const hicn_header_t *h, - size_t *bytes) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_signature_size (type, &h->protocol, bytes); -} - -int -hicn_packet_set_signature_size (hicn_format_t format, hicn_header_t *h, - size_t bytes) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_signature_size (type, &h->protocol, bytes); -} - -int -hicn_packet_get_signature_padding (hicn_format_t format, - const hicn_header_t *h, size_t *bytes) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_signature_padding (type, &h->protocol, - bytes); -} - -int -hicn_packet_set_signature_padding (hicn_format_t format, hicn_header_t *h, - size_t bytes) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_signature_padding (type, &h->protocol, - bytes); -} - -int -hicn_packet_set_signature_timestamp (hicn_format_t format, hicn_header_t *h, - uint64_t signature_timestamp) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_signature_timestamp (type, &h->protocol, - signature_timestamp); -} - -int -hicn_packet_get_signature_timestamp (hicn_format_t format, - const hicn_header_t *h, - uint64_t *signature_timestamp) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_signature_timestamp (type, &h->protocol, - signature_timestamp); -} - -int -hicn_packet_set_validation_algorithm (hicn_format_t format, hicn_header_t *h, - uint8_t validation_algorithm) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_validation_algorithm ( - type, &h->protocol, validation_algorithm); -} - -int -hicn_packet_get_validation_algorithm (hicn_format_t format, - const hicn_header_t *h, - uint8_t *validation_algorithm) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_validation_algorithm ( - type, &h->protocol, validation_algorithm); -} - -int -hicn_packet_set_key_id (hicn_format_t format, hicn_header_t *h, - uint8_t *key_id) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_key_id (type, &h->protocol, key_id); -} - -int -hicn_packet_get_key_id (hicn_format_t format, hicn_header_t *h, - uint8_t **key_id, uint8_t *key_id_length) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_key_id (type, &h->protocol, key_id, - key_id_length); -} - -int -hicn_packet_get_hoplimit (const hicn_header_t *h, u8 *hops) -{ - switch (HICN_IP_VERSION (h)) - { - case 6: - *hops = h->v6.ip.hlim; - break; - case 4: - *hops = h->v4.ip.ttl; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_hoplimit (hicn_header_t *h, u8 hops) -{ - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.ip.hlim = hops; - break; - case 4: - h->v4.ip.ttl = hops; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_is_interest (hicn_format_t format, const hicn_header_t *h, - int *ret) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->is_interest (type, &h->protocol, ret); -} - -int -hicn_packet_set_interest (hicn_format_t format, hicn_header_t *h) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->mark_packet_as_interest (type, &h->protocol); -} - -int -hicn_packet_set_data (hicn_format_t format, hicn_header_t *h) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->mark_packet_as_data (type, &h->protocol); -} - -int -hicn_packet_get_lifetime (hicn_format_t format, const hicn_header_t *h, - u32 *lifetime) -{ - hicn_type_t type = hicn_header_to_type (h); - return hicn_ops_vft[type.l1]->get_lifetime (type, &h->protocol, - (hicn_lifetime_t *) lifetime); -} - -int -hicn_packet_set_lifetime (hicn_format_t format, hicn_header_t *h, u32 lifetime) -{ - hicn_type_t type = hicn_header_to_type (h); - return hicn_ops_vft[type.l1]->set_lifetime (type, &h->protocol, - (hicn_lifetime_t) lifetime); -} - -int -hicn_packet_get_reserved_bits (const hicn_header_t *h, u8 *reserved_bits) -{ - switch (HICN_IP_VERSION (h)) - { - case 6: - *reserved_bits = (u8) (h->v6.tcp.reserved); - break; - case 4: - *reserved_bits = (u8) (h->v4.tcp.reserved); - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_reserved_bits (hicn_header_t *h, const u8 reserved_bits) -{ - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.reserved = reserved_bits; - break; - case 4: - h->v4.tcp.reserved = reserved_bits; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_get_payload_type (hicn_format_t format, const hicn_header_t *h, - hicn_payload_type_t *payload_type) -{ - hicn_type_t type = hicn_header_to_type (h); - return hicn_ops_vft[type.l1]->get_payload_type (type, &h->protocol, - payload_type); -} - -int -hicn_packet_set_payload_type (hicn_format_t format, hicn_header_t *h, - hicn_payload_type_t payload_type) -{ - hicn_type_t type = hicn_header_to_type (h); - return hicn_ops_vft[type.l1]->set_payload_type (type, &h->protocol, - payload_type); -} - -int -hicn_packet_set_syn (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_SYN; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_SYN; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_reset_syn (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_SYN; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_SYN; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_test_syn (hicn_format_t format, const hicn_header_t *h, bool *flag) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *flag = h->v6.tcp.flags & HICN_TCP_FLAG_SYN; - break; - case 4: - *flag = h->v4.tcp.flags & HICN_TCP_FLAG_SYN; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_ack (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_ACK; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_ACK; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_reset_ack (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_ACK; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_ACK; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_test_ack (hicn_format_t format, const hicn_header_t *h, bool *flag) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *flag = h->v6.tcp.flags & HICN_TCP_FLAG_ACK; - break; - case 4: - *flag = h->v4.tcp.flags & HICN_TCP_FLAG_ACK; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_rst (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_RST; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_RST; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_reset_rst (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_RST; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_RST; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_test_rst (hicn_format_t format, const hicn_header_t *h, bool *flag) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *flag = h->v6.tcp.flags & HICN_TCP_FLAG_RST; - break; - case 4: - *flag = h->v4.tcp.flags & HICN_TCP_FLAG_RST; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_fin (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_FIN; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_FIN; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_reset_fin (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_FIN; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_FIN; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_test_fin (hicn_format_t format, const hicn_header_t *h, bool *flag) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *flag = h->v6.tcp.flags & HICN_TCP_FLAG_FIN; - break; - case 4: - *flag = h->v4.tcp.flags & HICN_TCP_FLAG_FIN; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_ece (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags | HICN_TCP_FLAG_ECE; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags | HICN_TCP_FLAG_ECE; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_reset_ece (hicn_format_t format, hicn_header_t *h) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.flags = h->v6.tcp.flags & ~HICN_TCP_FLAG_ECE; - break; - case 4: - h->v4.tcp.flags = h->v4.tcp.flags & ~HICN_TCP_FLAG_ECE; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_test_ece (hicn_format_t format, const hicn_header_t *h, bool *flag) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *flag = h->v6.tcp.flags & HICN_TCP_FLAG_ECE; - break; - case 4: - *flag = h->v4.tcp.flags & HICN_TCP_FLAG_ECE; - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_src_port (hicn_format_t format, hicn_header_t *h, u16 src_port) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.sport = htons (src_port); - break; - case 4: - h->v4.tcp.sport = htons (src_port); - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_get_src_port (hicn_format_t format, const hicn_header_t *h, - u16 *src_port) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *src_port = ntohs (h->v6.tcp.sport); - break; - case 4: - *src_port = ntohs (h->v4.tcp.sport); - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_set_dst_port (hicn_format_t format, hicn_header_t *h, u16 dst_port) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - h->v6.tcp.dport = htons (dst_port); - break; - case 4: - h->v4.tcp.dport = htons (dst_port); - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_get_dst_port (hicn_format_t format, const hicn_header_t *h, - u16 *dst_port) -{ - if (!_is_tcp (format)) - { - return HICN_LIB_ERROR_UNEXPECTED; - } - - switch (HICN_IP_VERSION (h)) - { - case 6: - *dst_port = ntohs (h->v6.tcp.dport); - break; - case 4: - *dst_port = ntohs (h->v4.tcp.dport); - break; - default: - return HICN_LIB_ERROR_UNEXPECTED; - } - return HICN_LIB_ERROR_NONE; -} - -int -hicn_packet_copy_header (hicn_format_t format, const hicn_header_t *packet, - hicn_header_t *destination, bool copy_ah) -{ - size_t header_length = _is_ipv4 (format) * IPV4_HDRLEN; - header_length += _is_ipv6 (format) * IPV6_HDRLEN; - header_length += _is_icmp (format) * ICMP_HDRLEN; - header_length += _is_tcp (format) * TCP_HDRLEN; - header_length += _is_ah (format) * copy_ah * AH_HDRLEN; - - memcpy (destination, packet, header_length); - - return HICN_LIB_ERROR_NONE; -} - -#define _INTEREST 1 -#define _DATA 0 - -/* Interest */ - -int -hicn_interest_get_name (hicn_format_t format, const hicn_header_t *interest, - hicn_name_t *name) -{ - return hicn_packet_get_name (format, interest, name, _INTEREST); -} - -int -hicn_interest_set_name (hicn_format_t format, hicn_header_t *interest, - const hicn_name_t *name) -{ - return hicn_packet_set_name (format, interest, name, _INTEREST); -} - -int -hicn_interest_get_locator (hicn_format_t format, const hicn_header_t *interest, - ip_address_t *address) -{ - return hicn_packet_get_locator (format, interest, address, _INTEREST); -} - -int -hicn_interest_set_locator (hicn_format_t format, hicn_header_t *interest, - const ip_address_t *address) -{ - return hicn_packet_set_locator (format, interest, address, _INTEREST); -} - -int -hicn_interest_compare (const hicn_header_t *interest_1, - const hicn_header_t *interest_2) -{ - return hicn_packet_compare (interest_1, interest_2); -} - -int -hicn_interest_get_lifetime (const hicn_header_t *interest, u32 *lifetime) -{ - hicn_format_t format; - int rc = hicn_packet_get_format (interest, &format); - - if (rc) - return rc; - - return hicn_packet_get_lifetime (format, interest, lifetime); -} - -int -hicn_interest_set_lifetime (hicn_header_t *interest, u32 lifetime) -{ - hicn_format_t format; - int rc = hicn_packet_get_format (interest, &format); - - if (rc) - return rc; - - return hicn_packet_set_lifetime (format, interest, lifetime); -} - -int -hicn_interest_get_header_length (hicn_format_t format, - const hicn_header_t *interest, - size_t *header_length) -{ - return hicn_packet_get_header_length (format, interest, header_length); -} - -int -hicn_interest_get_payload_length (hicn_format_t format, - const hicn_header_t *interest, - size_t *payload_length) -{ - return hicn_packet_get_payload_length (format, interest, payload_length); -} - -int -hicn_interest_get_payload (hicn_format_t format, const hicn_header_t *interest, - u8 **payload, size_t *payload_size, bool hard_copy) -{ - return hicn_packet_get_payload (format, interest, payload, payload_size, - hard_copy); -} - -int -hicn_interest_set_payload (hicn_format_t format, hicn_header_t *interest, - const u8 *payload, size_t payload_length) -{ - return hicn_packet_set_payload (format, interest, payload, - (u16) payload_length); -} - -int -hicn_interest_reset_for_hash (hicn_format_t format, hicn_header_t *packet) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->reset_interest_for_hash (type, - &packet->protocol); -} - -/* Data */ - -int -hicn_data_get_name (hicn_format_t format, const hicn_header_t *data, - hicn_name_t *name) -{ - return hicn_packet_get_name (format, data, name, _DATA); -} - -int -hicn_data_set_name (hicn_format_t format, hicn_header_t *data, - const hicn_name_t *name) -{ - return hicn_packet_set_name (format, data, name, _DATA); -} - -int -hicn_data_get_locator (hicn_format_t format, const hicn_header_t *data, - ip_address_t *address) -{ - return hicn_packet_get_locator (format, data, address, _DATA); -} - -int -hicn_data_set_locator (hicn_format_t format, hicn_header_t *data, - const ip_address_t *address) -{ - return hicn_packet_set_locator (format, data, address, _DATA); -} - -int -hicn_data_compare (const hicn_header_t *data_1, const hicn_header_t *data_2) -{ - return hicn_packet_compare (data_1, data_2); -} - -int -hicn_data_get_expiry_time (const hicn_header_t *data, u32 *expiry_time) -{ - hicn_format_t format; - int rc = hicn_packet_get_format (data, &format); - - if (rc) - return rc; - - return hicn_packet_get_lifetime (format, data, expiry_time); -} - -int -hicn_data_set_expiry_time (hicn_header_t *data, u32 expiry_time) -{ - hicn_format_t format; - int rc = hicn_packet_get_format (data, &format); - - if (rc) - return rc; - - return hicn_packet_set_lifetime (format, data, - (hicn_lifetime_t) expiry_time); -} - -int -hicn_data_get_header_length (hicn_format_t format, hicn_header_t *data, - size_t *header_length) -{ - return hicn_packet_get_header_length (format, data, header_length); -} - -int -hicn_data_get_payload_length (hicn_format_t format, const hicn_header_t *data, - size_t *payload_length) -{ - return hicn_packet_get_payload_length (format, data, payload_length); -} - -int -hicn_data_get_path_label (const hicn_header_t *data, u32 *path_label) -{ - hicn_type_t type = hicn_header_to_type (data); - return hicn_ops_vft[type.l1]->get_data_pathlabel (type, &data->protocol, - path_label); -} - -int -hicn_data_set_path_label (hicn_header_t *data, u32 path_label) -{ - hicn_type_t type = hicn_header_to_type (data); - return hicn_ops_vft[type.l1]->set_data_pathlabel (type, &data->protocol, - path_label); -} - -int -hicn_data_set_payload (hicn_format_t format, hicn_header_t *data, - const u8 *payload, size_t payload_length) -{ - return hicn_packet_set_payload (format, data, payload, (u16) payload_length); -} - -int -hicn_data_get_payload (hicn_format_t format, const hicn_header_t *data, - u8 **payload, size_t *payload_size, bool hard_copy) -{ - return hicn_packet_get_payload (format, data, payload, payload_size, - hard_copy); -} - -int -hicn_data_reset_for_hash (hicn_format_t format, hicn_header_t *packet) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->reset_data_for_hash (type, &packet->protocol); -} - -int -hicn_data_is_last (hicn_format_t format, hicn_header_t *h, int *is_last) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->is_last_data (type, &h->protocol, is_last); -} - -int -hicn_data_set_last (hicn_format_t format, hicn_header_t *h) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->set_last_data (type, &h->protocol); -} - -int -hicn_packet_get_signature (hicn_format_t format, hicn_header_t *packet, - uint8_t **sign_buf) -{ - hicn_type_t type = hicn_format_to_type (format); - return hicn_ops_vft[type.l1]->get_signature (type, &packet->protocol, - sign_buf); -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/lib/src/face.c b/lib/src/face.c index 46b36e8cd..832cd0936 100644 --- a/lib/src/face.c +++ b/lib/src/face.c @@ -142,6 +142,12 @@ netdevice_cmp (const netdevice_t *nd1, const netdevice_t *nd2) return (nd1->index - nd2->index); } +bool +netdevice_is_empty (const netdevice_t *netdevice) +{ + return (netdevice->index != 0) || (netdevice->name[0] != '\0'); +} + /* Face state */ const char *_face_state_str[] = { @@ -181,8 +187,8 @@ face_initialize (face_t *face) int face_initialize_udp (face_t *face, const char *interface_name, - const ip_address_t *local_addr, u16 local_port, - const ip_address_t *remote_addr, u16 remote_port, + const hicn_ip_address_t *local_addr, u16 local_port, + const hicn_ip_address_t *remote_addr, u16 remote_port, int family) { if (!local_addr) @@ -264,9 +270,10 @@ face_create () } face_t * -face_create_udp (const char *interface_name, const ip_address_t *local_addr, - u16 local_port, const ip_address_t *remote_addr, - u16 remote_port, int family) +face_create_udp (const char *interface_name, + const hicn_ip_address_t *local_addr, u16 local_port, + const hicn_ip_address_t *remote_addr, u16 remote_port, + int family) { face_t *face = face_create (); if (face_initialize_udp (face, interface_name, local_addr, local_port, @@ -336,11 +343,11 @@ face_cmp (const face_t *f1, const face_t *f2) switch (f1->type) { case FACE_TYPE_HICN: - ret = ip_address_cmp (&f1->local_addr, &f2->local_addr, f1->family); + ret = hicn_ip_address_cmp (&f1->local_addr, &f2->local_addr); if (ret != 0) return ret; - ret = ip_address_cmp (&f1->remote_addr, &f2->remote_addr, f1->family); + ret = hicn_ip_address_cmp (&f1->remote_addr, &f2->remote_addr); if (ret != 0) return ret; @@ -348,7 +355,7 @@ face_cmp (const face_t *f1, const face_t *f2) case FACE_TYPE_TCP: case FACE_TYPE_UDP: - ret = ip_address_cmp (&f1->local_addr, &f2->local_addr, f1->family); + ret = hicn_ip_address_cmp (&f1->local_addr, &f2->local_addr); if (ret != 0) return ret; @@ -356,7 +363,7 @@ face_cmp (const face_t *f1, const face_t *f2) if (ret != 0) return ret; - ret = ip_address_cmp (&f1->remote_addr, &f2->remote_addr, f1->family); + ret = hicn_ip_address_cmp (&f1->remote_addr, &f2->remote_addr); if (ret != 0) return ret; @@ -376,19 +383,24 @@ face_cmp (const face_t *f1, const face_t *f2) size_t face_snprintf (char *s, size_t size, const face_t *face) { + char local[MAXSZ_IP_ADDRESS]; + char remote[MAXSZ_IP_ADDRESS]; + char tags[MAXSZ_POLICY_TAGS]; + + if (!hicn_ip_address_match_family (&face->local_addr, face->family)) + return 0; + if (!hicn_ip_address_match_family (&face->remote_addr, face->family)) + return 0; + + hicn_ip_address_snprintf (local, MAXSZ_IP_ADDRESS, &face->local_addr); + hicn_ip_address_snprintf (remote, MAXSZ_IP_ADDRESS, &face->remote_addr); + policy_tags_snprintf (tags, MAXSZ_POLICY_TAGS, face->tags); + switch (face->type) { case FACE_TYPE_HICN: { - char local[MAXSZ_IP_ADDRESS]; - char remote[MAXSZ_IP_ADDRESS]; - char tags[MAXSZ_POLICY_TAGS]; - - ip_address_snprintf (local, MAXSZ_IP_ADDRESS, &face->local_addr, - face->family); - ip_address_snprintf (remote, MAXSZ_IP_ADDRESS, &face->remote_addr, - face->family); - policy_tags_snprintf (tags, MAXSZ_POLICY_TAGS, face->tags); + return snprintf (s, size, "%s [%s -> %s] [%s]", face_type_str (face->type), local, remote, tags); } @@ -396,16 +408,6 @@ face_snprintf (char *s, size_t size, const face_t *face) case FACE_TYPE_TCP: case FACE_TYPE_UDP: { - char local[MAXSZ_IP_ADDRESS]; - char remote[MAXSZ_IP_ADDRESS]; - char tags[MAXSZ_POLICY_TAGS]; - - ip_address_snprintf (local, MAXSZ_IP_ADDRESS, &face->local_addr, - face->family); - ip_address_snprintf (remote, MAXSZ_IP_ADDRESS, &face->remote_addr, - face->family); - policy_tags_snprintf (tags, MAXSZ_POLICY_TAGS, face->tags); - return snprintf (s, size, "%s [%s:%d -> %s:%d] [%s]", face_type_str (face->type), local, face->local_port, remote, face->remote_port, tags); diff --git a/lib/src/mapme.c b/lib/src/mapme.c index b8e8eaed2..3f864e768 100644 --- a/lib/src/mapme.c +++ b/lib/src/mapme.c @@ -22,8 +22,44 @@ #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/protocol/ipv4.h> -#include <hicn/protocol/ipv6.h> +#include "protocol/ipv4.h" +#include "protocol/ipv6.h" +#include "protocol/icmprd.h" + +/** @brief MAP-Me packet header for IPv4 */ +typedef struct +{ + _ipv4_header_t ip; + _icmprd4_header_t icmp_rd; + seq_t seq; + u8 len; + u8 _pad[3]; +} hicn_mapme_v4_header_t; + +/** @brief MAP-Me packet header for IPv6 */ +typedef struct +{ + _ipv6_header_t ip; + _icmprd_header_t icmp_rd; + seq_t seq; + u8 len; + u8 _pad[3]; +} hicn_mapme_v6_header_t; + +/** @brief MAP-Me packet header (IP version agnostic) */ +typedef union +{ + hicn_mapme_v4_header_t v4; + hicn_mapme_v6_header_t v6; +} hicn_mapme_header_t; + +#define HICN_MAPME_V4_HDRLEN sizeof (hicn_mapme_v4_header_t) +#define HICN_MAPME_V6_HDRLEN sizeof (hicn_mapme_v6_header_t) + +static_assert (EXPECTED_MAPME_V4_HDRLEN == HICN_MAPME_V4_HDRLEN, + "Size of MAPME_V4 struct does not match its expected size."); +static_assert (EXPECTED_MAPME_V6_HDRLEN == HICN_MAPME_V6_HDRLEN, + "Size of MAPME_V6 struct does not match its expected size."); size_t hicn_mapme_v4_create_packet (u8 *buf, const hicn_prefix_t *prefix, @@ -96,7 +132,7 @@ hicn_mapme_create_packet (u8 *buf, const hicn_prefix_t *prefix, const mapme_params_t *params) { /* We currently ignore subsequent protocol definitions */ - if (PREDICT_TRUE (params->protocol == IPPROTO_IPV6)) + if (HICN_EXPECT_TRUE (params->protocol == IPPROTO_IPV6)) return hicn_mapme_v6_create_packet (buf, prefix, params); else return hicn_mapme_v4_create_packet (buf, prefix, params); @@ -105,7 +141,7 @@ hicn_mapme_create_packet (u8 *buf, const hicn_prefix_t *prefix, size_t hicn_mapme_v4_create_ack (u8 *buf, const mapme_params_t *params) { - ip4_address_t tmp; // tmp storage for swapping IP addresses for ACK + ipv4_address_t tmp; // tmp storage for swapping IP addresses for ACK hicn_mapme_v4_header_t *mh = (hicn_mapme_v4_header_t *) buf; tmp = mh->ip.daddr; @@ -121,7 +157,7 @@ hicn_mapme_v4_create_ack (u8 *buf, const mapme_params_t *params) size_t hicn_mapme_v6_create_ack (u8 *buf, const mapme_params_t *params) { - ip6_address_t tmp; // tmp storage for swapping IP addresses for ACK + ipv6_address_t tmp; // tmp storage for swapping IP addresses for ACK hicn_mapme_v6_header_t *mh = (hicn_mapme_v6_header_t *) buf; tmp = mh->ip.daddr; @@ -138,7 +174,7 @@ size_t hicn_mapme_create_ack (u8 *buf, const mapme_params_t *params) { /* We currently ignore subsequent protocol definitions */ - if (PREDICT_TRUE (params->protocol == IPPROTO_IPV6)) + if (HICN_EXPECT_TRUE (params->protocol == IPPROTO_IPV6)) return hicn_mapme_v6_create_ack (buf, params); else return hicn_mapme_v4_create_ack (buf, params); @@ -205,8 +241,9 @@ hicn_mapme_parse_packet (const u8 *packet, hicn_prefix_t *prefix, case 6: return hicn_mapme_v6_parse_packet (packet, prefix, params); default: - return HICN_LIB_ERROR_UNEXPECTED; + break; } + return HICN_LIB_ERROR_UNEXPECTED; } /* diff --git a/lib/src/name.c b/lib/src/name.c index 3bdcbbdb4..04c48cb4d 100644 --- a/lib/src/name.c +++ b/lib/src/name.c @@ -31,6 +31,8 @@ #include <hicn/name.h> #include <hicn/util/sstrncpy.h> +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + int hicn_name_create (const char *ip_address, u32 id, hicn_name_t *name) { @@ -55,11 +57,20 @@ hicn_name_create (const char *ip_address, u32 id, hicn_name_t *name) } int -hicn_name_create_from_ip_prefix (const ip_prefix_t *prefix, u32 id, +hicn_name_create_from_ip_address (const hicn_ip_address_t ip_address, + u32 suffix, hicn_name_t *name) +{ + name->prefix = ip_address; + name->suffix = suffix; + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_name_create_from_ip_prefix (const hicn_ip_prefix_t *prefix, u32 id, hicn_name_t *name) { - name->prefix.v6.as_u64[0] = prefix->address.v6.as_u64[0]; - name->prefix.v6.as_u64[1] = prefix->address.v6.as_u64[1]; + name->prefix = prefix->address; name->suffix = id; return HICN_LIB_ERROR_NONE; @@ -79,15 +90,15 @@ hicn_name_compare (const hicn_name_t *name_1, const hicn_name_t *name_2, return ret; } -int -hicn_name_hash (const hicn_name_t *name, u32 *hash, bool consider_suffix) +uint32_t +_hicn_name_get_hash (const hicn_name_t *name, bool consider_suffix) { - *hash = hash32 (&name->prefix, sizeof (name->prefix)); + uint32_t hash = hash32 (&name->prefix, sizeof (name->prefix)); if (consider_suffix) - *hash = cumulative_hash32 (&name->suffix, sizeof (name->suffix), *hash); + hash = cumulative_hash32 (&name->suffix, sizeof (name->suffix), hash); - return HICN_LIB_ERROR_NONE; + return hash; } int @@ -116,9 +127,9 @@ hicn_name_copy_prefix_to_destination (u8 *dst, const hicn_name_t *name) } int -hicn_name_set_seq_number (hicn_name_t *name, u32 seq_number) +hicn_name_set_suffix (hicn_name_t *name, hicn_name_suffix_t suffix) { - name->suffix = seq_number; + name->suffix = suffix; return HICN_LIB_ERROR_NONE; } @@ -149,7 +160,7 @@ hicn_name_to_sockaddr_address (const hicn_name_t *name, } int -hicn_name_to_ip_prefix (const hicn_name_t *name, ip_prefix_t *prefix) +hicn_name_to_hicn_ip_prefix (const hicn_name_t *name, hicn_ip_prefix_t *prefix) { int family, rc; rc = hicn_name_get_family (name, &family); @@ -211,24 +222,247 @@ hicn_name_get_family (const hicn_name_t *name, int *family) return HICN_LIB_ERROR_NONE; } +bool +hicn_name_is_v4 (const hicn_name_t *name) +{ + return _is_inet4 (name); +} + int -hicn_prefix_create_from_ip_prefix (const ip_prefix_t *ip_prefix, +hicn_name_snprintf (char *s, size_t size, const hicn_name_t *name) +{ + int n, rc; + n = hicn_ip_address_snprintf (s, size, &name->prefix); + if (n < 0 || n >= size) + return n; + rc = snprintf (s + n, size - n, "|%d", name->suffix); + if (rc < 0) + return rc; + return rc + n; +} + +int +hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix, hicn_prefix_t *prefix) { - switch (ip_prefix->family) + if (hicn_ip_prefix->family != AF_INET || hicn_ip_prefix->family != AF_INET6) + return HICN_LIB_ERROR_INVALID_IP_ADDRESS; + prefix->name = hicn_ip_prefix->address; + prefix->len = (u8) (hicn_ip_prefix->len); + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_name_cmp (const hicn_name_t *n1, const hicn_name_t *n2) +{ + int rc = hicn_ip_address_cmp (&n1->prefix, &n2->prefix); + if (rc != 0) + return rc; + return n2->suffix - n1->suffix; +} + +bool +hicn_name_equals (const hicn_name_t *n1, const hicn_name_t *n2) +{ + return (hicn_name_cmp (n1, n2) == 0); +} + +int +hicn_prefix_create_from_ip_address_len (const hicn_ip_address_t *ip_address, + uint8_t len, hicn_prefix_t *prefix) +{ + prefix->name = *ip_address; + prefix->len = len; + + return HICN_LIB_ERROR_NONE; +} + +hicn_prefix_t * +hicn_prefix_dup (const hicn_prefix_t *prefix) +{ + hicn_prefix_t *copy = malloc (sizeof (hicn_prefix_t)); + if (!copy) + goto ERR_MALLOC; + if (hicn_prefix_copy (copy, prefix) < 0) + goto ERR_COPY; + return copy; + +ERR_COPY: + free (copy); +ERR_MALLOC: + return NULL; +} + +int +hicn_prefix_copy (hicn_prefix_t *dst, const hicn_prefix_t *src) +{ + dst->name = src->name; + dst->len = src->len; + return 0; +} + +bool +hicn_prefix_is_v4 (const hicn_prefix_t *prefix) +{ + return hicn_ip_address_is_v4 (&prefix->name); +} + +/* + * The ip address is in network byte order (big endian, msb last) in + * hicn_{prefix,name}_t, as in ip_address_t which builds upon struct in*_addr, + * But the bits are in host order... so we cannot use builtin functions to get + * the position of the first 1 unless we swap bytes as was done previously, + * which is costly and non-essential. + */ + +uint64_t +_log2_nbo (uint64_t val) +{ + assert (val != 0); /* There is at least 1 bit set (network byte order) */ + + uint64_t result = 0; + + if (val & 0xFFFFFFFF00000000) + val = val >> 32; + else + /* The first 32 bits of val are 0 */ + result = result | 32; + + if (val & 0xFFFF0000) + val = val >> 16; + else + result = result | 16; + + if (val & 0xFF00) + val = val >> 8; + else + result = result | 8; + + /* Val now contains the byte with at last 1 bit set (host bit order) */ + if (val & 0xF0) { - case AF_INET: - prefix->name.v4.as_u32 = ip_prefix->address.v4.as_u32; - break; - case AF_INET6: - prefix->name.v6.as_u64[0] = ip_prefix->address.v6.as_u64[0]; - prefix->name.v6.as_u64[1] = ip_prefix->address.v6.as_u64[1]; - break; - default: - return HICN_LIB_ERROR_INVALID_IP_ADDRESS; + val = val >> 4; + result = result | 4; } - prefix->len = (u8) (ip_prefix->len); + if (val & 0xC) + { + val = val >> 2; + result = result | 2; + } + if (val & 0x2) + { + val = val >> 1; + result = result | 1; + } + + return result; +} + +uint32_t +hicn_prefix_lpm (const hicn_prefix_t *p1, const hicn_prefix_t *p2) +{ + uint32_t prefix_len = 0; + /* Test each block of 64 bits as a whole */ + for (unsigned i = 0; i < 2; i++) + { + + /* Check for differences in the two u64 */ + uint64_t diff = p1->name.v6.as_u64[i] ^ p2->name.v6.as_u64[i]; + if (diff) + { + /* + * As the ip_address_t mimics in*_addr and has network byte order + * (and host bit order, we cannot directly use 64-bit operations: + * + * Example: + * + * bits | 7 .. 0 | 15 14 13 12 11 10 9 8 | .. | 127 .. 120 | + * diff | | 1 0 1 0 0 0 0 0 | .. | | + * ^ + * bit of interest ---------+ + */ + prefix_len += _log2_nbo (diff); + break; + } + prefix_len += 8 * sizeof (uint64_t); + } + + /* Bound the returned prefix length by the length of all input */ + return MIN (prefix_len, + MIN (hicn_prefix_get_len (p1), hicn_prefix_get_len (p2))); +} + +void +hicn_prefix_clear (hicn_prefix_t *prefix, uint8_t start_from) +{ + uint8_t *buffer = prefix->name.v6.as_u8; + + /* Compute the offset of the byte from which to clear the name... */ + uint8_t offset = start_from / 8; + if (hicn_prefix_is_v4 (prefix)) + offset += IP_ADDRESS_V4_OFFSET_LEN; /* Ignore padding */ + /* ... and the position of the first bit to clear */ + uint8_t pos = start_from % 8; + + /* Mask to clear specific bits at offset... + * pos 7 6 5 4 3 2 1 0 (eg. start_from = 19, pos = 3) + * mask 0 0 0 0 0 1 1 1 (= 1<<pos - 1) + * */ + buffer[offset] &= 1 << (pos - 1); + /* ... then fully clear remaining bytes */ + for (uint8_t i = offset + 1; i < HICN_PREFIX_MAX_LEN; i++) + buffer[i] = 0; +} + +void +hicn_prefix_truncate (hicn_prefix_t *prefix, uint8_t len) +{ + hicn_prefix_clear (prefix, len); + prefix->len = len; +} + +int +hicn_prefix_cmp (const hicn_prefix_t *p1, const hicn_prefix_t *p2) +{ + if (p1->len != p2->len) + return p2->len - p1->len; + return hicn_ip_address_cmp (&p1->name, &p2->name); +} + +bool +hicn_prefix_equals (const hicn_prefix_t *p1, const hicn_prefix_t *p2) +{ + return hicn_prefix_cmp (p1, p2) == 0; +} + +int +hicn_prefix_snprintf (char *s, size_t size, const hicn_prefix_t *prefix) +{ + hicn_ip_prefix_t ip_prefix = { .family = + hicn_ip_address_get_family (&prefix->name), + .address = prefix->name, + .len = prefix->len }; + return hicn_ip_prefix_snprintf (s, size, &ip_prefix); +} + +uint8_t +hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos) +{ + assert (pos <= hicn_prefix_get_len (prefix)); + const hicn_ip_address_t *address = hicn_prefix_get_ip_address (prefix); + return hicn_ip_address_get_bit (address, pos); +} + +int +hicn_prefix_get_ip_prefix (const hicn_prefix_t *prefix, + hicn_ip_prefix_t *ip_prefix) +{ + *ip_prefix = + (hicn_ip_prefix_t){ .family = hicn_ip_address_get_family (&prefix->name), + .address = prefix->name, + .len = prefix->len }; return HICN_LIB_ERROR_NONE; } diff --git a/lib/src/ops.c b/lib/src/ops.c index 20362d69d..0174a3902 100644 --- a/lib/src/ops.c +++ b/lib/src/ops.c @@ -22,8 +22,9 @@ #include <netinet/in.h> #endif #include <stdlib.h> -#include <hicn/ops.h> -#include <hicn/header.h> + +#include "ops.h" +#include "protocol.h" extern const hicn_ops_t hicn_ops_ipv4; extern const hicn_ops_t hicn_ops_icmp; @@ -34,16 +35,22 @@ extern const hicn_ops_t hicn_ops_new; extern const hicn_ops_t hicn_ops_ah; /* Declare empty operations (terminates recursion on protocol layers) */ -DECLARE_init_packet_header (none, NONE); + +int +none_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) +{ + pkbuf->payload = pkbuf->len; + return HICN_LIB_ERROR_NONE; +} + DECLARE_get_interest_locator (none, NONE); DECLARE_set_interest_locator (none, NONE); DECLARE_get_interest_name (none, NONE); DECLARE_set_interest_name (none, NONE); DECLARE_get_interest_name_suffix (none, NONE); DECLARE_set_interest_name_suffix (none, NONE); -DECLARE_is_interest (none, NONE); -DECLARE_mark_packet_as_interest (none, NONE); -DECLARE_mark_packet_as_data (none, NONE); +DECLARE_get_type (none, NONE); +DECLARE_set_type (none, NONE); DECLARE_reset_interest_for_hash (none, NONE); DECLARE_get_data_locator (none, NONE); DECLARE_set_data_locator (none, NONE); @@ -51,25 +58,18 @@ DECLARE_get_data_name (none, NONE); DECLARE_set_data_name (none, NONE); DECLARE_get_data_name_suffix (none, NONE); DECLARE_set_data_name_suffix (none, NONE); -DECLARE_get_data_pathlabel (none, NONE); -DECLARE_set_data_pathlabel (none, NONE); -DECLARE_update_data_pathlabel (none, NONE); +DECLARE_get_data_path_label (none, NONE); +DECLARE_set_data_path_label (none, NONE); +DECLARE_update_data_path_label (none, NONE); DECLARE_reset_data_for_hash (none, NONE); DECLARE_get_lifetime (none, NONE); DECLARE_set_lifetime (none, NONE); -DECLARE_get_source_port (none, NONE); -DECLARE_get_dest_port (none, NONE); -DECLARE_set_source_port (none, NONE); -DECLARE_set_dest_port (none, NONE); DECLARE_update_checksums (none, NONE); +DECLARE_update_checksums_incremental (none, NONE); DECLARE_verify_checksums (none, NONE); DECLARE_rewrite_interest (none, NONE); DECLARE_rewrite_data (none, NONE); -DECLARE_get_length (none, NONE); -DECLARE_get_header_length (none, NONE); -DECLARE_get_current_header_length (none, NONE); -DECLARE_get_payload_length (none, NONE); -DECLARE_set_payload_length (none, NONE); +DECLARE_set_payload_len (none, NONE); DECLARE_get_payload_type (none, NONE); DECLARE_set_payload_type (none, NONE); DECLARE_get_signature_size (none, NONE); @@ -81,11 +81,18 @@ DECLARE_get_validation_algorithm (none, NONE); DECLARE_set_key_id (none, NONE); DECLARE_get_key_id (none, NONE); DECLARE_get_signature (none, NONE); +DECLARE_has_signature (none, NONE); DECLARE_get_signature_padding (none, NONE); DECLARE_set_signature_padding (none, NONE); DECLARE_is_last_data (none, NONE); DECLARE_set_last_data (none, NONE); -DECLARE_HICN_OPS (none); +DECLARE_get_ttl (none, NONE); +DECLARE_set_ttl (none, NONE); +DECLARE_get_src_port (none, NONE); +DECLARE_set_src_port (none, NONE); +DECLARE_get_dst_port (none, NONE); +DECLARE_set_dst_port (none, NONE); +DECLARE_HICN_OPS (none, 0); /** * @brief Virtual function table for packet operations @@ -99,8 +106,8 @@ const hicn_ops_t *const hicn_ops_vft[] = { /* 41 */[IPPROTO_IPV6] = &hicn_ops_ipv6, /* 51 */[IPPROTO_AH] = &hicn_ops_ah, /* 58 */[IPPROTO_ICMPV6] = &hicn_ops_icmp, + /* 59 */[IPPROTO_NONE] = &hicn_ops_none, /* 98 */[IPPROTO_ENCAP] = &hicn_ops_new, - [IPPROTO_NONE] = &hicn_ops_none, }; /* diff --git a/lib/src/ops.h b/lib/src/ops.h new file mode 100644 index 000000000..886d75cd5 --- /dev/null +++ b/lib/src/ops.h @@ -0,0 +1,1082 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file base.h + * @brief Protocol-independent packet operations + */ + +#ifndef HICN_OPS_H +#define HICN_OPS_H + +#include <assert.h> +#include <stdlib.h> + +#include <hicn/base.h> +#include <hicn/error.h> +#include <hicn/name.h> +#include <hicn/packet.h> // HICN_OPAQUE_LEN +#include <hicn/util/ip_address.h> + +#include "protocol.h" + +/* + * In order to provide fast lookup and accelerate packet operations, we allow + * ourselves to use a header cache structure under the responsibility of the + * caller, and that can be associated to each packet. This structure is exposed + * as a opaque pointer. + */ + +/* + * hICN operations on packets + * + * All prototypes take an hicn_type_t parameter as their first argument, as + * this decides the sequence of protocols that are being used by the different + * operations. + */ + +typedef struct hicn_ops_s +{ + const char *name; + + size_t header_len; + + /** + * @brief Initialize the headers of the hicn packet + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + */ + int (*init_packet_header) (hicn_packet_buffer_t *pkbuf, size_t pos); + + /** + * @brief Retrieves an Interest locator + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] ip_address - Retrieved locator + * @return hICN error code + */ + int (*get_interest_locator) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, + hicn_ip_address_t *ip_address); + + /** + * @brief Sets an Interest locator + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] ip_address - Locator to set + * @return hICN error code + */ + int (*set_interest_locator) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address); + + /** + * @brief Retrieves an Interest name + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] name - Retrieved name + * @return hICN error code + */ + int (*get_interest_name) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, hicn_name_t *name); + + /** + * @brief Sets an Interest name + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] name - Name to set + * @return hICN error code + */ + int (*set_interest_name) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_name_t *name); + + /** + * @brief Retrieves an Interest name suffix + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] suffix - Retrieved name suffix + * @return hICN error code + */ + int (*get_interest_name_suffix) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, + hicn_name_suffix_t *suffix); + + /** + * @brief Sets an Interest name suffix + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] suffix - Name suffix to set + * @return hICN error code + */ + int (*set_interest_name_suffix) (const hicn_packet_buffer_t *pkbuf, + size_t pos, + const hicn_name_suffix_t *suffix); + + /** + * @brief Get packet type + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Position within the network layers + * @param [out] type - Packet type + * @return hICN error code + */ + int (*get_type) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type); + + /** + * @brief Set flag to mark current packet as interest + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Position within the network layers + * @param [in] type - Packet type + * @return hICN error code + */ + int (*set_type) (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type); + + /** + * @brief Clear the necessary Interest fields in order to hash it + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @return hICN error code + */ + int (*reset_interest_for_hash) (hicn_packet_buffer_t *pkbuf, size_t pos); + + /** + * @brief Retrieves a Data locator + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] ip_address - Retrieved locator + * @return hICN error code + */ + int (*get_data_locator) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_ip_address_t *ip_address); + + /** + * @brief Sets a Data locator + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] ip_address - Locator to set + * @return hICN error code + */ + int (*set_data_locator) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address); + + /** + * @brief Retrieves a Data name + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] name - Retrieved name + * @return hICN error code + */ + int (*get_data_name) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_name_t *name); + + /** + * @brief Sets a Data name + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] name - Name to set + * @return hICN error code + */ + int (*set_data_name) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_name_t *name); + + /** + * @brief Retrieves a Data name suffix + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] suffix - Retrieved name suffix + * @return hICN error code + */ + int (*get_data_name_suffix) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, hicn_name_suffix_t *suffix); + + /** + * @brief Sets a Data name suffix + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] suffix - Name suffix to set + * @return hICN error code + */ + int (*set_data_name_suffix) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_name_suffix_t *suffix); + + /** + * @brief Retrieves a Data path_label + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [out] path_label - Retrieved path_label + * @return hICN error code + */ + int (*get_data_path_label) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, hicn_path_label_t *path_label); + + /** + * @brief Sets a Data path_label + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] path_label - Pathlabel to set + * @return hICN error code + */ + int (*set_data_path_label) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_path_label_t path_label); + + /** + * @brief Update a Data path_label with a new face identifier + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] path_label - Face identifier used to update path_label + * @return hICN error code + */ + int (*update_data_path_label) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_faceid_t face_id); + + /** + * @brief Clear the necessary Data fields in order to hash it + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @return hICN error code + */ + int (*reset_data_for_hash) (hicn_packet_buffer_t *pkbuf, size_t pos); + + /** + * @brief Retrieves an Interest or Data lifetime + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Current position in the sequence of headers while + * executing command + * @param [out] path_label - Retrieved lifetime + * @return hICN error code + */ + int (*get_lifetime) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_lifetime_t *lifetime); + + /** + * @brief Sets an Interest or Data lifetime + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] path_label - Lifetime to set + * @return hICN error code + */ + int (*set_lifetime) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_lifetime_t lifetime); + + /** + * @brief Update all checksums in packet headers + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] partial_csum - Partial checksum (set to 0, used internally to + * carry intermediate values from IP pseudo-header) + * @param [in] payload_len - Payload len (can be set to ~0, retrieved + * and used internally to carry payload len across protocol headers) + * @return hICN error code + * + * Payload len is initialized during the initial steps (eg. IP) if not + * provided (value is ~0), and not ignored (value is 0). + */ + int (*update_checksums) (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len); + + /** + * @brief Update all checksums in packet headers + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] old_val - Pointer to the old value + * @param [in] new_val - Pointer to the new value + * @param [in] size - Size of the changed value + * @param [in] skip_first - Skip the first protocol (ignore IP checksum) + * @return hICN error code + */ + int (*update_checksums_incremental) (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first); + + /** + * @brief Validate all checksums in packet headers + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] partial_csum - Partial checksum, or zero if no partial + * checksum available + * @param [in] payload_len - Payload len (can be set to ~0, retrieved + * and used internally to carry payload len across protocol headers) + * @return hICN error code + */ + int (*verify_checksums) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + u16 partial_csum, size_t payload_len); + + /** + * @brief Rewrite an Interest packet header (locator) + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] addr_new - New locator + * @param [in] addr_old - Old locator (set to NULL, used internally to + * compute incremental checksums) + * @return hICN error code + */ + int (*rewrite_interest) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old); + + /** + * @brief Rewrite a Data packet header (locator + path_label) + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @param [in] addr_new - New locator + * @param [in] addr_old - Old locator (set to NULL, used internally to + * compute incremental checksums) + * @param [in] face_id - Face identifier used to update path_label + * @param [in] reset_pl - If not zero, reset the current path_label + * before update it + * @return hICN error code + */ + int (*rewrite_data) (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, + const hicn_faceid_t face_id, u8 reset_pl); + + /** + * @brief Return the packet len + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @parma [out] len - Returned packet len + * @return hICN error code + */ + int (*get_len) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + size_t *len); + + /** + * @brief Return the current packet header len + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @parma [out] header_len - Returned packet current header len + * @return hICN error code + */ + int (*get_current_header_len) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, size_t *header_len); + + /** + * @brief Sets the packet paylaod len + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Depth in the header stack + * @parma [out] payload_len - Payload len to set + * @return hICN error code + */ + int (*set_payload_len) (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t payload_len); + + /** + * @brief Retrieves an Interest or Data signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Current position in the sequence of headers while + * executing command + * @param [out] signature_size - Retrieved signature size + * @return hICN error code + */ + int (*get_signature_size) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, size_t *signature_size); + + /** + * @brief Sets an Interest or Data signature size + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] signature_size - Signature size to set + * @return hICN error code + */ + int (*set_signature_size) (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t signature_size); + + /** + * @brief Sets an Interest or Data signature padding between maximum size and + * real size + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] signature_size - Signature size to set + * @return hICN error code + */ + int (*set_signature_padding) (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t signature_padding); + + /** + * @brief gets an Interest or Data signature padding between maximum size and + * real size + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] signature_size - retrieve the padding between maximum size and + * real size + * @return hICN error code + */ + int (*get_signature_padding) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, size_t *signature_padding); + + /** + * @brief Gets the signature timestamp + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [out] signature_timestamp - Retrieved signature timestamp + * @return hICN error code + */ + int (*get_signature_timestamp) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, + uint64_t *signature_timestamp); + + /** + * @brief Sets the signature timestamp + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] signature_timestamp - Signature timestamp to set + * @return hICN error code + */ + int (*set_signature_timestamp) (const hicn_packet_buffer_t *pkbuf, + size_t pos, uint64_t signature_timestamp); + + /** + * @brief Gets the signature validation algorithm + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [out] validation_algorithm - Retrieved validation_algorithm + * @return hICN error code + */ + int (*get_validation_algorithm) (const hicn_packet_buffer_t *pkbuf, + const size_t pos, + uint8_t *validation_algorithm); + + /** + * @brief Sets the signature validation algorithm + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] validation_algorithm - Validation algorithm enumeration + * @return hICN error code + */ + int (*set_validation_algorithm) (const hicn_packet_buffer_t *pkbuf, + size_t pos, uint8_t validation_algorithm); + + /** + * @brief Gets the key id + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [out] key_id - Retrieved key id first byte address + * @return hICN error code + */ + int (*get_key_id) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + uint8_t **key_id, uint8_t *key_id_size); + + /** + * @brief Sets the key id + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] key_id - Key id first byte address + * @return hICN error code + */ + int (*set_key_id) (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *key_id, size_t size); + + /** + * @brief Get a pointer to the signature field in the packet + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [out] signature - Pointer to the memory region holding the + * signature + * @return hICN error code + */ + int (*get_signature) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + uint8_t **signature); + + /** + * @brief Returns whether the packet holds a signature. + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [out] flag - Boolean indicating whether the packet has a signature. + * @return hICN error code + */ + int (*has_signature) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + bool *flag); + + /** + * @brief Set payload type of the packet + * @param [in] pkbuf - hICN packet buffer + * @param [in,out] pos - Current position in the sequence of headers while + * executing command + * @param [in] payload_type - The payload type of this packet + * @return hICN error code + */ + int (*set_payload_type) (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t payload_type); + + /** + * @brief Get payload type from the packet + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Current position in the sequence of headers while + * executing command + * @param [out] payload_type - The payload type of this packet + * @return hICN error code + */ + int (*get_payload_type) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_payload_type_t *payload_type); + + /** + * @brief Check if data packet is last one. + * @param [in] pkbuf - hICN packet buffer + * @param [in] pos - Current position in the sequence of headers while + * executing command + * @param [out] is_last - 1 if last data, 0 otherwise + * @return hICN error code + */ + int (*is_last_data) (const hicn_packet_buffer_t *pkbuf, const size_t pos, + int *is_last); + + /** + * @brief Mark data packet as last + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * executing command + * @return hICN error code + */ + int (*set_last_data) (const hicn_packet_buffer_t *pkbuf, size_t pos); + + /** + * @brief Returns the packet TTL + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] hops - Pointer to the variable receiving the TTL value + * @return hICN error code + */ + int (*get_ttl) (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 *hops); + + /** + * @brief Returns the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] hops - The TTL value to set + * @return hICN error code + */ + int (*set_ttl) (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 hops); + + /** + * @brief Returns the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] port - Pointer to the variable that will receive the port + * number + * @return hICN error code + */ + int (*get_src_port) (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 *port); + + /** + * @brief Sets the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] port - The port number to set + * @return hICN error code + */ + int (*set_src_port) (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 port); + + /** + * @brief Returns the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] port - Pointer to the variable that will receive the port + * number + * @return hICN error code + */ + int (*get_dst_port) (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 *port); + + /** + * @brief Sets the packet source port + * @param [in] pkbuf - hICN packet buffer + * @param [in, out] pos - Current position in the sequence of headers while + * @param [out] port - The port number to set + * @return hICN error code + */ + int (*set_dst_port) (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 port); +} hicn_ops_t; + +#define DECLARE_HICN_OPS(protocol, len) \ + const hicn_ops_t hicn_ops_##protocol = { \ + ATTR_INIT (name, #protocol), \ + ATTR_INIT (header_len, len), \ + ATTR_INIT (init_packet_header, protocol##_init_packet_header), \ + ATTR_INIT (get_interest_locator, protocol##_get_interest_locator), \ + ATTR_INIT (set_interest_locator, protocol##_set_interest_locator), \ + ATTR_INIT (get_interest_name, protocol##_get_interest_name), \ + ATTR_INIT (set_interest_name, protocol##_set_interest_name), \ + ATTR_INIT (get_interest_name_suffix, \ + protocol##_get_interest_name_suffix), \ + ATTR_INIT (set_interest_name_suffix, \ + protocol##_set_interest_name_suffix), \ + ATTR_INIT (get_type, protocol##_get_type), \ + ATTR_INIT (set_type, protocol##_set_type), \ + ATTR_INIT (reset_interest_for_hash, protocol##_reset_interest_for_hash), \ + ATTR_INIT (get_data_locator, protocol##_get_data_locator), \ + ATTR_INIT (set_data_locator, protocol##_set_data_locator), \ + ATTR_INIT (get_data_name, protocol##_get_data_name), \ + ATTR_INIT (set_data_name, protocol##_set_data_name), \ + ATTR_INIT (get_data_name_suffix, protocol##_get_data_name_suffix), \ + ATTR_INIT (set_data_name_suffix, protocol##_set_data_name_suffix), \ + ATTR_INIT (get_data_path_label, protocol##_get_data_path_label), \ + ATTR_INIT (set_data_path_label, protocol##_set_data_path_label), \ + ATTR_INIT (update_data_path_label, protocol##_update_data_path_label), \ + ATTR_INIT (reset_data_for_hash, protocol##_reset_data_for_hash), \ + ATTR_INIT (get_lifetime, protocol##_get_lifetime), \ + ATTR_INIT (set_lifetime, protocol##_set_lifetime), \ + ATTR_INIT (update_checksums, protocol##_update_checksums), \ + ATTR_INIT (update_checksums_incremental, \ + protocol##_update_checksums_incremental), \ + ATTR_INIT (verify_checksums, protocol##_verify_checksums), \ + ATTR_INIT (rewrite_interest, protocol##_rewrite_interest), \ + ATTR_INIT (rewrite_data, protocol##_rewrite_data), \ + ATTR_INIT (set_payload_len, protocol##_set_payload_len), \ + ATTR_INIT (get_payload_type, protocol##_get_payload_type), \ + ATTR_INIT (set_payload_type, protocol##_set_payload_type), \ + ATTR_INIT (get_signature_size, protocol##_get_signature_size), \ + ATTR_INIT (get_signature_timestamp, protocol##_get_signature_timestamp), \ + ATTR_INIT (set_signature_timestamp, protocol##_set_signature_timestamp), \ + ATTR_INIT (get_validation_algorithm, \ + protocol##_get_validation_algorithm), \ + ATTR_INIT (set_validation_algorithm, \ + protocol##_set_validation_algorithm), \ + ATTR_INIT (get_key_id, protocol##_get_key_id), \ + ATTR_INIT (set_key_id, protocol##_set_key_id), \ + ATTR_INIT (get_signature, protocol##_get_signature), \ + ATTR_INIT (has_signature, protocol##_has_signature), \ + ATTR_INIT (set_signature_padding, protocol##_set_signature_padding), \ + ATTR_INIT (set_signature_size, protocol##_set_signature_size), \ + ATTR_INIT (get_signature_padding, protocol##_get_signature_padding), \ + ATTR_INIT (is_last_data, protocol##_is_last_data), \ + ATTR_INIT (get_ttl, protocol##_get_ttl), \ + ATTR_INIT (set_ttl, protocol##_set_ttl), \ + ATTR_INIT (get_src_port, protocol##_get_src_port), \ + ATTR_INIT (set_src_port, protocol##_set_src_port), \ + ATTR_INIT (get_dst_port, protocol##_get_dst_port), \ + ATTR_INIT (set_dst_port, protocol##_set_dst_port), \ + } + +/** + * @brief Protocol-independent packet operations VFT + * NOTE: The following declarations should be kept in order + */ +extern const hicn_ops_t *const hicn_ops_vft[]; + +#define PROT(pkbuf, pos) \ + ((pos < (HICN_FORMAT_LEN - 1)) ? \ + hicn_packet_get_format (pkbuf).as_u8[(pos) + 1] : \ + IPPROTO_NONE) + +#define CALL_CHILD(method, pkbuf, pos, ...) \ + hicn_ops_vft[PROT (pkbuf, (pos))]->method (pkbuf, (pos) + 1, ##__VA_ARGS__); + +#define CALL(method, pkbuf, ...) CALL_CHILD (method, pkbuf, -1, ##__VA_ARGS__) + +/** Shortcuts to entry points in VFT */ +#define HICN_OPS4 hicn_ops_vft[IPPROTO_IP] +#define HICN_OPS6 hicn_ops_vft[IPPROTO_IPV6] + +/* Helpers for simple declarations */ + +#define DECLARE_init_packet_header(protocol, error) \ + int protocol##_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_interest_locator(protocol, error) \ + int protocol##_get_interest_locator (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + hicn_ip_address_t *ip_address) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_interest_locator(protocol, error) \ + int protocol##_set_interest_locator (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + const hicn_ip_address_t *ip_address) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_interest_name(protocol, error) \ + int protocol##_get_interest_name (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, hicn_name_t *name) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_interest_name(protocol, error) \ + int protocol##_set_interest_name (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, const hicn_name_t *name) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_interest_name_suffix(protocol, error) \ + int protocol##_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + hicn_name_suffix_t *suffix) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_interest_name_suffix(protocol, error) \ + int protocol##_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + const hicn_name_suffix_t *suffix) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_type(protocol, error) \ + int protocol##_get_type (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, hicn_packet_type_t *type) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_type(protocol, error) \ + int protocol##_set_type (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, hicn_packet_type_t type) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_reset_interest_for_hash(protocol, error) \ + int protocol##_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, \ + size_t pos) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_data_locator(protocol, error) \ + int protocol##_get_data_locator (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + hicn_ip_address_t *ip_address) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_data_locator(protocol, error) \ + int protocol##_set_data_locator (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + const hicn_ip_address_t *ip_address) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_data_name(protocol, error) \ + int protocol##_get_data_name (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, hicn_name_t *name) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_data_name(protocol, error) \ + int protocol##_set_data_name (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, const hicn_name_t *name) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_data_name_suffix(protocol, error) \ + int protocol##_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + hicn_name_suffix_t *suffix) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_data_name_suffix(protocol, error) \ + int protocol##_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + const hicn_name_suffix_t *suffix) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_data_path_label(protocol, error) \ + int protocol##_get_data_path_label (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + hicn_path_label_t *path_label) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_data_path_label(protocol, error) \ + int protocol##_set_data_path_label (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + const hicn_path_label_t path_label) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_update_data_path_label(protocol, error) \ + int protocol##_update_data_path_label (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + const hicn_faceid_t face_id) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_reset_data_for_hash(protocol, error) \ + int protocol##_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, \ + size_t pos) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_lifetime(protocol, error) \ + int protocol##_get_lifetime (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, hicn_lifetime_t *lifetime) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_lifetime(protocol, error) \ + int protocol##_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + const hicn_lifetime_t lifetime) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_update_checksums(protocol, error) \ + int protocol##_update_checksums (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, u16 partial_csum, \ + size_t payload_len) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_update_checksums_incremental(protocol, error) \ + int protocol##_update_checksums_incremental ( \ + const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *old_val, \ + u16 *new_val, u8 size, bool skip_first) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_verify_checksums(protocol, error) \ + int protocol##_verify_checksums (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, u16 partial_csum, \ + size_t payload_len) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_rewrite_interest(protocol, error) \ + int protocol##_rewrite_interest ( \ + const hicn_packet_buffer_t *pkbuf, size_t pos, \ + const hicn_ip_address_t *addr_new, hicn_ip_address_t *addr_old) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_rewrite_data(protocol, error) \ + int protocol##_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + const hicn_ip_address_t *addr_new, \ + hicn_ip_address_t *addr_old, \ + const hicn_faceid_t face_id, u8 reset_pl) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_payload_len(protocol, error) \ + int protocol##_set_payload_len (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, size_t payload_len) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_payload_type(protocol, error) \ + int protocol##_get_payload_type (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + hicn_payload_type_t *payload_type) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_payload_type(protocol, error) \ + int protocol##_set_payload_type (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + hicn_payload_type_t payload_type) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_signature_size(protocol, error) \ + int protocol##_get_signature_size (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + size_t *signature_size) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_signature_size(protocol, error) \ + int protocol##_set_signature_size (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, size_t signature_size) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_signature_padding(protocol, error) \ + int protocol##_set_signature_padding (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, size_t padding) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_signature_padding(protocol, error) \ + int protocol##_get_signature_padding (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, size_t *padding) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_signature_timestamp(protocol, error) \ + int protocol##_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + uint64_t signature_timestamp) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_signature_timestamp(protocol, error) \ + int protocol##_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + uint64_t *signature_timestamp) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_validation_algorithm(protocol, error) \ + int protocol##_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, \ + size_t pos, \ + uint8_t validation_algorithm) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_validation_algorithm(protocol, error) \ + int protocol##_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, \ + uint8_t *validation_algorithm) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_key_id(protocol, error) \ + int protocol##_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + uint8_t *key_id, size_t size) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_key_id(protocol, error) \ + int protocol##_get_key_id (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, uint8_t **key_id, \ + uint8_t *key_id_size) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_signature(protocol, error) \ + int protocol##_get_signature (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, uint8_t **signature) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_has_signature(protocol, error) \ + int protocol##_has_signature (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, bool *flag) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_is_last_data(protocol, error) \ + int protocol##_is_last_data (const hicn_packet_buffer_t *pkbuf, \ + const size_t pos, int *is_last) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_last_data(protocol, error) \ + int protocol##_set_last_data (const hicn_packet_buffer_t *pkbuf, \ + size_t pos) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_ttl(protocol, error) \ + int protocol##_get_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + u8 *hops) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_ttl(protocol, error) \ + int protocol##_set_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + u8 hops) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_src_port(protocol, error) \ + int protocol##_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + u16 *port) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_src_port(protocol, error) \ + int protocol##_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + u16 port) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_get_dst_port(protocol, error) \ + int protocol##_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + u16 *port) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#define DECLARE_set_dst_port(protocol, error) \ + int protocol##_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, \ + u16 port) \ + { \ + return HICN_LIB_ERROR_##error; \ + } + +#endif /* HICN_OPS_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/packet.c b/lib/src/packet.c new file mode 100644 index 000000000..ccef568cd --- /dev/null +++ b/lib/src/packet.c @@ -0,0 +1,833 @@ +/* + * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file packet.c + * @brief Implementation of the compatibility layer. + */ +#ifndef _WIN32 +#include <netinet/in.h> +#endif +#include <string.h> // memset +#include <stddef.h> // offsetof + +#include <hicn/common.h> +#include <hicn/packet.h> +#include <hicn/error.h> +#include <hicn/name.h> +#include <hicn/util/log.h> +#include "ops.h" + +#define member_size(type, member) sizeof (((type *) 0)->member) +#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a))) + +#define HICN_NAME_COMPONENT_SIZE 2 + +hicn_packet_format_t +hicn_packet_get_format (const hicn_packet_buffer_t *pkbuf) +{ + return pkbuf->format; +} + +void +hicn_packet_set_format (hicn_packet_buffer_t *pkbuf, + hicn_packet_format_t format) +{ + pkbuf->format = format; +} + +hicn_packet_type_t +hicn_packet_get_type (const hicn_packet_buffer_t *pkbuf) +{ + return pkbuf->type; +} + +void +hicn_packet_set_type (hicn_packet_buffer_t *pkbuf, hicn_packet_type_t type) +{ + pkbuf->type = type; +} + +bool +hicn_packet_is_interest (const hicn_packet_buffer_t *pkbuf) +{ + return pkbuf->type == HICN_PACKET_TYPE_INTEREST; +} + +bool +hicn_packet_is_data (const hicn_packet_buffer_t *pkbuf) +{ + return pkbuf->type == HICN_PACKET_TYPE_DATA; +} + +bool +hicn_packet_is_undefined (const hicn_packet_buffer_t *pkbuf) +{ + return pkbuf->type == HICN_PACKET_TYPE_UNDEFINED; +} + +int +hicn_packet_init_header (hicn_packet_buffer_t *pkbuf, + size_t additional_header_size) +{ + if (hicn_packet_is_undefined (pkbuf)) + return HICN_LIB_ERROR_UNEXPECTED; + if (hicn_packet_get_format (pkbuf).as_u32 == HICN_PACKET_FORMAT_NONE.as_u32) + return HICN_LIB_ERROR_UNEXPECTED; + if (!pkbuf_get_header (pkbuf)) + return HICN_LIB_ERROR_UNEXPECTED; + pkbuf->len = 0; + pkbuf->payload = 0; + + int rc = CALL (init_packet_header, pkbuf); + + /* + * Additional header size is there for the signature, and assumes the AH + * header is always located at the end... + */ + pkbuf->len += additional_header_size; + pkbuf->payload += additional_header_size; + + return rc; +} + +int +hicn_packet_reset (hicn_packet_buffer_t *pkbuf) +{ + memset (pkbuf, 0, sizeof (hicn_packet_buffer_t)); + hicn_packet_set_format (pkbuf, HICN_PACKET_FORMAT_NONE); + hicn_packet_set_type (pkbuf, HICN_PACKET_TYPE_UNDEFINED); + hicn_packet_set_len (pkbuf, 0); + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_analyze (hicn_packet_buffer_t *pkbuf) +{ + u8 *header = pkbuf_get_header (pkbuf); + u8 protocol; + u16 offset = 0; + bool has_signature; + size_t signature_size; + int rc; + + hicn_packet_format_t *format = &pkbuf->format; + + /* Bootstrap: assume IP packet, and get version from header */ + switch (HICN_IP_VERSION (pkbuf_get_header (pkbuf))) + { + case 4: + protocol = IPPROTO_IP; + break; + case 6: + protocol = IPPROTO_IPV6; + break; + default: + goto ERR; + } + + format->as_u32 = 0; + for (unsigned i = 0; i < HICN_FORMAT_LEN; i++) + { + format->as_u8[i] = protocol; + + /* Next protocol + increment offset */ + switch (protocol) + { + + /* + * All packets either start with IPv4 or IPv6, so we take the + * opportunity to update packet length there + */ + case IPPROTO_IP: + { + if (i > 0) + goto ERR; +#ifdef OPAQUE_IP + pkbuf->ipv4 = offset; +#else + assert (offset == 0); +#endif /* OPAQUE_IP */ + _ipv4_header_t *ipv4 = (_ipv4_header_t *) (header + offset); + protocol = ipv4->protocol; + offset += IPV4_HDRLEN; + + // hicn_packet_set_len (pkbuf, htons (ipv4->len)); + if (hicn_packet_get_len (pkbuf) != htons (ipv4->len)) + { + ERROR ("Invalid packet size in IPv4 header %d != %d", + htons (ipv4->len), hicn_packet_get_len (pkbuf)); + goto ERR; + } + break; + } + case IPPROTO_IPV6: + { + if (i > 0) + goto ERR; +#ifdef OPAQUE_IP + pkbuf->ipv6 = offset; +#else + assert (offset == 0); +#endif /* OPAQUE_IP */ + _ipv6_header_t *ipv6 = (_ipv6_header_t *) (header + offset); + protocol = ipv6->nxt; + offset += IPV6_HDRLEN; + // hicn_packet_set_len (pkbuf, IPV6_HDRLEN + htons (ipv6->len)); + if (hicn_packet_get_len (pkbuf) != IPV6_HDRLEN + htons (ipv6->len)) + { + ERROR ("Invalid packet size in IPv6 header %d != %d", + IPV6_HDRLEN + htons (ipv6->len), + hicn_packet_get_len (pkbuf)); + goto ERR; + } + break; + } + case IPPROTO_TCP: + pkbuf->tcp = offset; + /* After TCP, we might eventually have a AH header */ + rc = CALL_CHILD (has_signature, pkbuf, i - 1, &has_signature); + if (rc < 0) + goto ERR; + protocol = has_signature ? IPPROTO_AH : IPPROTO_NONE; + offset += TCP_HDRLEN; + break; + case IPPROTO_UDP: + pkbuf->udp = offset; + protocol = IPPROTO_ENCAP; + offset += UDP_HDRLEN; + break; + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + pkbuf->icmp = offset; + /* After ICMP, we might eventually have a AH header */ + // CALL_CHILD (has_signature, pkbuf, i - 1, &has_signature); + protocol = /* has_signature ? IPPROTO_AH : */ IPPROTO_NONE; + offset += ICMP_HDRLEN; + break; + + case IPPROTO_ENCAP: + pkbuf->newhdr = offset; + /* After ENCAP, we might eventually have a AH header */ + rc = CALL_CHILD (has_signature, pkbuf, i - 1, &has_signature); + if (rc < 0) + goto ERR; + protocol = has_signature ? IPPROTO_AH : IPPROTO_NONE; + offset += NEW_HDRLEN; + break; + + case IPPROTO_AH: + pkbuf->ah = offset; + protocol = IPPROTO_NONE; + offset += AH_HDRLEN; + + rc = CALL_CHILD (get_signature_size, pkbuf, i - 1, &signature_size); + if (rc < 0) + goto ERR; + offset += signature_size; + break; + + case IPPROTO_NONE: + /* NONE until we terminate the list of protocols */ + break; + + default: + goto ERR; + } + } + pkbuf->payload = offset; + + rc = CALL (get_type, pkbuf, &pkbuf->type); + if (rc < 0) + goto ERR; + + return HICN_LIB_ERROR_NONE; + +ERR: + *format = HICN_PACKET_FORMAT_NONE; + pkbuf->type = HICN_PACKET_TYPE_UNDEFINED; + return HICN_LIB_ERROR_UNEXPECTED; +} + +int +hicn_packet_set_buffer (hicn_packet_buffer_t *pkbuf, u8 *buffer, + uint16_t buffer_size, uint16_t len) +{ + pkbuf_set_header (pkbuf, buffer); + pkbuf->buffer_size = buffer_size; + pkbuf->len = len; + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_get_buffer (const hicn_packet_buffer_t *pkbuf, u8 **buffer, + uint16_t *buffer_size, uint16_t *len) +{ + *buffer = pkbuf_get_header (pkbuf); + *buffer_size = pkbuf->buffer_size; + *len = pkbuf->len; + return HICN_LIB_ERROR_NONE; +} + +size_t +hicn_packet_get_len (const hicn_packet_buffer_t *pkbuf) +{ + return pkbuf->len; +} + +int +hicn_packet_set_len (hicn_packet_buffer_t *pkbuf, size_t len) +{ + pkbuf->len = len; + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_get_header_len (const hicn_packet_buffer_t *pkbuf, size_t *len) +{ + *len = pkbuf->payload; + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_get_payload_len (const hicn_packet_buffer_t *pkbuf, size_t *len) +{ + *len = hicn_packet_get_len (pkbuf) - pkbuf->payload; + return HICN_LIB_ERROR_NONE; +} + +// XXX this fails with chained membufs in libtransport +int +hicn_packet_set_payload (const hicn_packet_buffer_t *pkbuf, const u8 *payload, + u16 payload_len) +{ + memcpy (pkbuf_get_header (pkbuf) + pkbuf->payload, payload, payload_len); + + return CALL (set_payload_len, pkbuf, payload_len); +} + +int +hicn_packet_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload, + size_t *payload_size, bool hard_copy) +{ + size_t payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload; + + if (hard_copy) + { + memcpy (payload, pkbuf_get_header (pkbuf) + pkbuf->payload, payload_len); + } + else + { + *payload = pkbuf_get_header (pkbuf) + pkbuf->payload; + } + + return HICN_LIB_ERROR_NONE; +} + +/* Header fields manipulation */ + +int +hicn_packet_get_header_length_from_format (hicn_packet_format_t format, + size_t *header_length) +{ + *header_length = 0; + for (unsigned i = 0; i < HICN_FORMAT_LEN; i++) + { + *header_length += hicn_ops_vft[format.as_u8[i]]->header_len; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_compute_checksum (const hicn_packet_buffer_t *pkbuf) +{ + return CALL (update_checksums, pkbuf, 0, ~0); +} + +int +hicn_packet_compute_header_checksum (const hicn_packet_buffer_t *pkbuf, + u16 init_sum) +{ + /* payload_len == 0: ignore payload */ + return CALL (update_checksums, pkbuf, init_sum, 0); +} + +int +hicn_packet_check_integrity_no_payload (const hicn_packet_buffer_t *pkbuf, + u16 init_sum) +{ + return CALL (verify_checksums, pkbuf, init_sum, 0); +} + +int +hicn_packet_set_payload_length (const hicn_packet_buffer_t *pkbuf, + const size_t payload_len) +{ + return CALL (set_payload_len, pkbuf, payload_len); +} + +int +hicn_packet_compare (const hicn_packet_buffer_t *pkbuf1, + const hicn_packet_buffer_t *pkbuf2) +{ + + hicn_packet_format_t format1 = hicn_packet_get_format (pkbuf1); + hicn_packet_format_t format2 = hicn_packet_get_format (pkbuf2); + + if (format1.as_u32 != format2.as_u32) + return HICN_LIB_ERROR_UNEXPECTED; + + size_t len1 = hicn_packet_get_len (pkbuf1); + size_t len2 = hicn_packet_get_len (pkbuf2); + + if (len1 != len2) + return HICN_LIB_ERROR_UNEXPECTED; + + return memcmp (pkbuf_get_header (pkbuf1), pkbuf_get_header (pkbuf2), len1); +} + +int +hicn_packet_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name) +{ + switch (pkbuf->type) + { + case HICN_PACKET_TYPE_INTEREST: + return hicn_interest_get_name (pkbuf, name); + case HICN_PACKET_TYPE_DATA: + return hicn_data_get_name (pkbuf, name); + default: + return HICN_LIB_ERROR_UNEXPECTED; + } +} + +int +hicn_packet_set_name (const hicn_packet_buffer_t *pkbuf, + const hicn_name_t *name) +{ + switch (pkbuf->type) + { + case HICN_PACKET_TYPE_INTEREST: + return hicn_interest_set_name (pkbuf, name); + case HICN_PACKET_TYPE_DATA: + return hicn_data_set_name (pkbuf, name); + default: + return HICN_LIB_ERROR_UNEXPECTED; + } +} + +int +hicn_packet_get_locator (const hicn_packet_buffer_t *pkbuf, + hicn_ip_address_t *address) +{ + switch (pkbuf->type) + { + case HICN_PACKET_TYPE_INTEREST: + return hicn_interest_get_locator (pkbuf, address); + case HICN_PACKET_TYPE_DATA: + return hicn_data_get_locator (pkbuf, address); + default: + return HICN_LIB_ERROR_UNEXPECTED; + } +} + +int +hicn_packet_set_locator (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *address) +{ + switch (pkbuf->type) + { + case HICN_PACKET_TYPE_INTEREST: + return hicn_interest_set_locator (pkbuf, address); + case HICN_PACKET_TYPE_DATA: + return hicn_data_set_locator (pkbuf, address); + default: + return HICN_LIB_ERROR_UNEXPECTED; + } +} + +int +hicn_packet_get_signature_size (const hicn_packet_buffer_t *pkbuf, + size_t *bytes) +{ + return CALL (get_signature_size, pkbuf, bytes); +} + +int +hicn_packet_set_signature_size (const hicn_packet_buffer_t *pkbuf, + size_t bytes) +{ + return CALL (set_signature_size, pkbuf, bytes); +} + +int +hicn_packet_get_signature_padding (const hicn_packet_buffer_t *pkbuf, + size_t *bytes) +{ + return CALL (get_signature_padding, pkbuf, bytes); +} + +int +hicn_packet_set_signature_padding (const hicn_packet_buffer_t *pkbuf, + size_t bytes) +{ + return CALL (set_signature_padding, pkbuf, bytes); +} + +int +hicn_packet_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, + uint64_t signature_timestamp) +{ + return CALL (set_signature_timestamp, pkbuf, signature_timestamp); +} + +int +hicn_packet_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, + uint64_t *signature_timestamp) +{ + return CALL (get_signature_timestamp, pkbuf, signature_timestamp); +} + +int +hicn_packet_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, + uint8_t validation_algorithm) +{ + return CALL (set_validation_algorithm, pkbuf, validation_algorithm); +} + +int +hicn_packet_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, + uint8_t *validation_algorithm) +{ + return CALL (get_validation_algorithm, pkbuf, validation_algorithm); +} + +int +hicn_packet_set_key_id (const hicn_packet_buffer_t *pkbuf, uint8_t *key_id, + size_t key_len) +{ + return CALL (set_key_id, pkbuf, key_id, key_len); +} + +int +hicn_packet_get_key_id (const hicn_packet_buffer_t *pkbuf, uint8_t **key_id, + uint8_t *key_id_len) +{ + return CALL (get_key_id, pkbuf, key_id, key_id_len); +} + +int +hicn_packet_get_lifetime (const hicn_packet_buffer_t *pkbuf, + hicn_lifetime_t *lifetime) +{ + return CALL (get_lifetime, pkbuf, lifetime); +} + +int +hicn_packet_set_lifetime (const hicn_packet_buffer_t *pkbuf, + hicn_lifetime_t lifetime) +{ + return CALL (set_lifetime, pkbuf, lifetime); +} + +int +hicn_packet_get_payload_type (const hicn_packet_buffer_t *pkbuf, + hicn_payload_type_t *payload_type) +{ + return CALL (get_payload_type, pkbuf, payload_type); +} + +int +hicn_packet_set_payload_type (const hicn_packet_buffer_t *pkbuf, + hicn_payload_type_t payload_type) +{ + return CALL (set_payload_type, pkbuf, payload_type); +} + +int +hicn_packet_save_header (const hicn_packet_buffer_t *pkbuf, u8 *header, + size_t *header_len, bool copy_ah) +{ + hicn_packet_format_t format = hicn_packet_get_format (pkbuf); + if (copy_ah || !_is_ah (format)) + { + int rc = hicn_packet_get_header_len (pkbuf, header_len); + if (HICN_LIB_IS_ERROR (rc)) + return rc; + } + else + { + /* Copy up until the ah header (which we assume is last) */ + *header_len = pkbuf->ah; + } + + memcpy (header, pkbuf_get_header (pkbuf), *header_len); + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_load_header (const hicn_packet_buffer_t *pkbuf, const u8 *header, + size_t header_len) +{ + memcpy (pkbuf_get_header (pkbuf), header, header_len); + + return HICN_LIB_ERROR_NONE; +} + +/* Interest */ + +int +hicn_interest_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name) +{ + return CALL (get_interest_name, pkbuf, name); +} + +int +hicn_interest_set_name (const hicn_packet_buffer_t *pkbuf, + const hicn_name_t *name) +{ + return CALL (set_interest_name, pkbuf, name); +} + +int +hicn_interest_get_locator (const hicn_packet_buffer_t *pkbuf, + hicn_ip_address_t *address) +{ + return CALL (get_interest_locator, pkbuf, address); +} + +int +hicn_interest_set_locator (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *address) +{ + return CALL (set_interest_locator, pkbuf, address); +} + +int +hicn_interest_compare (const hicn_packet_buffer_t *pkbuf1, + const hicn_packet_buffer_t *pkbuf2) +{ + return hicn_packet_compare (pkbuf1, pkbuf2); +} + +int +hicn_interest_get_lifetime (const hicn_packet_buffer_t *pkbuf, + hicn_lifetime_t *lifetime) +{ + return hicn_packet_get_lifetime (pkbuf, lifetime); +} + +int +hicn_interest_set_lifetime (const hicn_packet_buffer_t *pkbuf, + hicn_lifetime_t lifetime) +{ + return hicn_packet_set_lifetime (pkbuf, lifetime); +} + +int +hicn_interest_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload, + size_t *payload_size, bool hard_copy) +{ + return hicn_packet_get_payload (pkbuf, payload, payload_size, hard_copy); +} + +int +hicn_interest_set_payload (const hicn_packet_buffer_t *pkbuf, + const u8 *payload, size_t payload_len) +{ + return hicn_packet_set_payload (pkbuf, payload, (u16) payload_len); +} + +int +hicn_interest_reset_for_hash (hicn_packet_buffer_t *pkbuf) +{ + return CALL (reset_interest_for_hash, pkbuf); +} + +/* Data */ + +int +hicn_data_get_name (const hicn_packet_buffer_t *pkbuf, hicn_name_t *name) +{ + return CALL (get_data_name, pkbuf, name); +} + +int +hicn_data_set_name (const hicn_packet_buffer_t *pkbuf, const hicn_name_t *name) +{ + return CALL (set_data_name, pkbuf, name); +} + +int +hicn_data_get_locator (const hicn_packet_buffer_t *pkbuf, + hicn_ip_address_t *address) +{ + return CALL (get_data_locator, pkbuf, address); +} + +int +hicn_data_set_locator (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *address) +{ + return CALL (set_data_locator, pkbuf, address); +} + +int +hicn_data_compare (const hicn_packet_buffer_t *pkbuf1, + const hicn_packet_buffer_t *pkbuf2) +{ + return hicn_packet_compare (pkbuf1, pkbuf2); +} + +int +hicn_data_get_expiry_time (const hicn_packet_buffer_t *pkbuf, + hicn_lifetime_t *expiry_time) +{ + return hicn_packet_get_lifetime (pkbuf, expiry_time); +} + +int +hicn_data_set_expiry_time (const hicn_packet_buffer_t *pkbuf, + hicn_lifetime_t expiry_time) +{ + return hicn_packet_set_lifetime (pkbuf, expiry_time); +} + +/* Path label */ + +int +hicn_data_get_path_label (const hicn_packet_buffer_t *pkbuf, + hicn_path_label_t *path_label) +{ + return CALL (get_data_path_label, pkbuf, path_label); +} + +int +hicn_get_path_label (const hicn_packet_buffer_t *pkbuf, + hicn_path_label_t *path_label) +{ + if (!hicn_packet_is_data (pkbuf)) + return INVALID_PATH_LABEL; + return hicn_data_get_path_label (pkbuf, path_label); +} + +int +hicn_data_set_path_label (const hicn_packet_buffer_t *pkbuf, + hicn_path_label_t path_label) +{ + return CALL (set_data_path_label, pkbuf, path_label); +} + +int +hicn_data_set_payload (const hicn_packet_buffer_t *pkbuf, const u8 *payload, + size_t payload_len) +{ + return hicn_packet_set_payload (pkbuf, payload, (u16) payload_len); +} + +int +hicn_data_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload, + size_t *payload_size, bool hard_copy) +{ + return hicn_packet_get_payload (pkbuf, payload, payload_size, hard_copy); +} + +int +hicn_data_reset_for_hash (hicn_packet_buffer_t *pkbuf) +{ + return CALL (reset_data_for_hash, pkbuf); +} + +int +hicn_data_is_last (const hicn_packet_buffer_t *pkbuf, int *is_last) +{ + return CALL (is_last_data, pkbuf, is_last); +} + +int +hicn_data_set_last (const hicn_packet_buffer_t *pkbuf) +{ + return CALL (set_last_data, pkbuf); +} + +int +hicn_packet_get_signature (const hicn_packet_buffer_t *pkbuf, + uint8_t **sign_buf) +{ + return CALL (get_signature, pkbuf, sign_buf); +} + +int +hicn_packet_get_ttl (const hicn_packet_buffer_t *pkbuf, u8 *hops) +{ + return CALL (get_ttl, pkbuf, hops); +} + +int +hicn_packet_set_ttl (const hicn_packet_buffer_t *pkbuf, u8 hops) +{ + return CALL (set_ttl, pkbuf, hops); +} + +int +hicn_packet_get_src_port (const hicn_packet_buffer_t *pkbuf, u16 *port) +{ + return CALL (get_src_port, pkbuf, port); +} + +int +hicn_packet_set_src_port (const hicn_packet_buffer_t *pkbuf, u16 port) +{ + return CALL (set_src_port, pkbuf, port); +} + +int +hicn_packet_get_dst_port (const hicn_packet_buffer_t *pkbuf, u16 *port) +{ + return CALL (get_dst_port, pkbuf, port); +} + +int +hicn_packet_set_dst_port (const hicn_packet_buffer_t *pkbuf, u16 port) +{ + return CALL (set_dst_port, pkbuf, port); +} + +int +hicn_interest_rewrite (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) +{ + return CALL (rewrite_interest, pkbuf, addr_new, addr_old); +} + +int +hicn_data_rewrite (const hicn_packet_buffer_t *pkbuf, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) +{ + return CALL (rewrite_data, pkbuf, addr_new, addr_old, face_id, reset_pl); +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/includes/hicn/protocol.h b/lib/src/protocol.h index fb142e4c3..58bbb2ac2 100644 --- a/lib/includes/hicn/protocol.h +++ b/lib/src/protocol.h @@ -29,19 +29,6 @@ #include "protocol/udp.h" #include "protocol/new.h" -typedef union -{ - _new_header_t newhdr; - _ipv4_header_t ipv4; - _ipv6_header_t ipv6; - _tcp_header_t tcp; - _udp_header_t udp; - _icmp_header_t icmp; - _icmprd_header_t icmprd; - _ah_header_t ah; - void *bytes; -} hicn_protocol_t; - #endif /* HICN_PROTOCOL_H */ /* diff --git a/lib/src/protocol/ah.c b/lib/src/protocol/ah.c index c9ed40179..9cc747ac8 100644 --- a/lib/src/protocol/ah.c +++ b/lib/src/protocol/ah.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -18,12 +18,12 @@ * @brief hICN operations for AH header */ -#include <string.h> // memcpy #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/header.h> -#include <hicn/ops.h> -#include <hicn/protocol/ah.h> +#include <string.h> // memcpy + +#include "../ops.h" +#include "ah.h" DECLARE_get_interest_locator (ah, UNEXPECTED); DECLARE_set_interest_locator (ah, UNEXPECTED); @@ -31,218 +31,248 @@ DECLARE_get_interest_name (ah, UNEXPECTED); DECLARE_set_interest_name (ah, UNEXPECTED); DECLARE_get_interest_name_suffix (ah, UNEXPECTED); DECLARE_set_interest_name_suffix (ah, UNEXPECTED); -DECLARE_is_interest (ah, UNEXPECTED); -DECLARE_mark_packet_as_interest (ah, UNEXPECTED); -DECLARE_mark_packet_as_data (ah, UNEXPECTED); +DECLARE_get_type (ah, UNEXPECTED); +DECLARE_set_type (ah, UNEXPECTED); DECLARE_get_data_locator (ah, UNEXPECTED); DECLARE_set_data_locator (ah, UNEXPECTED); DECLARE_get_data_name (ah, UNEXPECTED); DECLARE_set_data_name (ah, UNEXPECTED); DECLARE_get_data_name_suffix (ah, UNEXPECTED); DECLARE_set_data_name_suffix (ah, UNEXPECTED); -DECLARE_get_data_pathlabel (ah, UNEXPECTED); -DECLARE_set_data_pathlabel (ah, UNEXPECTED); -DECLARE_update_data_pathlabel (ah, UNEXPECTED); +DECLARE_get_data_path_label (ah, UNEXPECTED); +DECLARE_set_data_path_label (ah, UNEXPECTED); +DECLARE_update_data_path_label (ah, UNEXPECTED); DECLARE_get_lifetime (ah, UNEXPECTED); DECLARE_set_lifetime (ah, UNEXPECTED); -DECLARE_get_source_port (ah, UNEXPECTED); -DECLARE_get_dest_port (ah, UNEXPECTED); -DECLARE_set_source_port (ah, UNEXPECTED); -DECLARE_set_dest_port (ah, UNEXPECTED); -DECLARE_get_payload_length (ah, UNEXPECTED); -DECLARE_set_payload_length (ah, UNEXPECTED); +// DECLARE_get_payload_len (ah, UNEXPECTED); +DECLARE_set_payload_len (ah, UNEXPECTED); DECLARE_get_payload_type (ah, UNEXPECTED); DECLARE_set_payload_type (ah, UNEXPECTED); DECLARE_is_last_data (ah, UNEXPECTED); DECLARE_set_last_data (ah, UNEXPECTED); +DECLARE_get_ttl (ah, UNEXPECTED); +DECLARE_set_ttl (ah, UNEXPECTED); +DECLARE_get_src_port (ah, UNEXPECTED); +DECLARE_set_src_port (ah, UNEXPECTED); +DECLARE_get_dst_port (ah, UNEXPECTED); +DECLARE_set_dst_port (ah, UNEXPECTED); int -ah_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +ah_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - /* *INDENT-OFF* */ - h->ah = (_ah_header_t){ + pkbuf->ah = pkbuf->len; + if (AH_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += AH_HDRLEN; + + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + /* clang-format off */ + *ah = (_ah_header_t){ .nh = (u8) 0, .payloadlen = (u8) 0, .reserved = (u16) 0, }; - /* *INDENT-ON* */ - return CHILD_OPS (init_packet_header, type, h); + /* clang-format on */ + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -ah_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) +ah_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + size_t signature_size; - int rc = - hicn_ops_vft[type.l1]->get_signature_size (type, h, &signature_size); + int rc = CALL (get_signature_size, pkbuf, &signature_size); if (rc < 0) return rc; - memset (&(h->ah.validationPayload), 0, signature_size); - h->ah.signaturePadding = 0; - return CHILD_OPS (reset_interest_for_hash, type, h); + memset (&(ah->validationPayload), 0, signature_size); + ah->signaturePadding = 0; + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -ah_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +ah_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + size_t signature_size; - int rc = - hicn_ops_vft[type.l1]->get_signature_size (type, h, &signature_size); + int rc = CALL (get_signature_size, pkbuf, &signature_size); if (rc < 0) return rc; - memset (&(h->ah.validationPayload), 0, signature_size); - h->ah.signaturePadding = 0; - return CHILD_OPS (reset_interest_for_hash, type, h); + memset (&(ah->validationPayload), 0, signature_size); + ah->signaturePadding = 0; + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -ah_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +ah_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { /* Nothing to do as there is no checksum in AH */ return HICN_LIB_ERROR_NONE; } int -ah_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +ah_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 *old_val, u16 *new_val, u8 size, + bool skip_first) { - /* Nothing to do as there is no checksum in AH */ - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val, + new_val, size, false); } int -ah_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +ah_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - /* Nothing to do on signature */ + /* Nothing to do as there is no checksum in AH */ return HICN_LIB_ERROR_NONE; } int -ah_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +ah_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { /* Nothing to do on signature */ return HICN_LIB_ERROR_NONE; } int -ah_get_length (hicn_type_t type, const hicn_protocol_t *h, size_t *length) -{ - return HICN_LIB_ERROR_NOT_IMPLEMENTED; -} - -int -ah_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ah_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { - *header_length = AH_HDRLEN + (h->ah.payloadlen << 2); + /* Nothing to do on signature */ return HICN_LIB_ERROR_NONE; } int -ah_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ah_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **signature) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *header_length = AH_HDRLEN + (h->ah.payloadlen << 2) + child_header_length; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + *signature = ah->validationPayload; return HICN_LIB_ERROR_NONE; } int -ah_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature) +ah_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag) { - *signature = h->ah.validationPayload; + *flag = true; return HICN_LIB_ERROR_NONE; } int -ah_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, +ah_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *signature_size) { - *signature_size = h->ah.payloadlen << 2; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + *signature_size = ah->payloadlen << 2; return HICN_LIB_ERROR_NONE; } int -ah_set_signature_size (hicn_type_t type, hicn_protocol_t *h, - const size_t signature_size) +ah_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t signature_size) { - h->ah.payloadlen = signature_size >> 2; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + ah->payloadlen = signature_size >> 2; return HICN_LIB_ERROR_NONE; } int -ah_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, +ah_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t signature_timestamp) { + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + uint64_t netwok_order_timestamp = htonll (signature_timestamp); - memcpy (h->ah.timestamp_as_u8, &netwok_order_timestamp, sizeof (uint64_t)); + memcpy (ah->timestamp_as_u8, &netwok_order_timestamp, sizeof (uint64_t)); return HICN_LIB_ERROR_NONE; } int -ah_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, +ah_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t *signature_timestamp) { - memcpy (signature_timestamp, h->ah.timestamp_as_u8, sizeof (uint64_t)); + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + memcpy (signature_timestamp, ah->timestamp_as_u8, sizeof (uint64_t)); *signature_timestamp = ntohll (*signature_timestamp); return HICN_LIB_ERROR_NONE; } int -ah_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, +ah_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t validation_algorithm) { - h->ah.validationAlgorithm = validation_algorithm; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + ah->validationAlgorithm = validation_algorithm; return HICN_LIB_ERROR_NONE; } int -ah_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, +ah_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *validation_algorithm) { - *validation_algorithm = h->ah.validationAlgorithm; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + *validation_algorithm = ah->validationAlgorithm; return HICN_LIB_ERROR_NONE; } int -ah_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, size_t padding) +ah_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t padding) { - h->ah.signaturePadding = padding; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + ah->signaturePadding = padding; return HICN_LIB_ERROR_NONE; } int -ah_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, +ah_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *padding) { - *padding = h->ah.signaturePadding; + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + *padding = ah->signaturePadding; return HICN_LIB_ERROR_NONE; } int -ah_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +ah_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id, + size_t size) { - memcpy (h->ah.keyId, key_id, sizeof (h->ah.keyId)); + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + if (size != sizeof (ah->keyId)) + return HICN_LIB_ERROR_INVALID_PARAMETER; + + memcpy (ah->keyId, key_id, sizeof (ah->keyId)); return HICN_LIB_ERROR_NONE; } int -ah_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, +ah_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t **key_id, uint8_t *key_id_size) { - *key_id = h->ah.keyId; - *key_id_size = sizeof (h->ah.keyId); + _ah_header_t *ah = pkbuf_get_ah (pkbuf); + + *key_id = ah->keyId; + *key_id_size = sizeof (ah->keyId); return HICN_LIB_ERROR_NONE; } -DECLARE_HICN_OPS (ah); +DECLARE_HICN_OPS (ah, AH_HDRLEN); /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/protocol/ah.h b/lib/src/protocol/ah.h new file mode 100644 index 000000000..ee124f92a --- /dev/null +++ b/lib/src/protocol/ah.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file protocol/ah.h + * @brief AH packet header + */ +#ifndef HICN_PROTOCOL_AH_H +#define HICN_PROTOCOL_AH_H + +#include <hicn/common.h> + +/* + * The TCP PSH flag is set to indicate TCP payload in fact contains a AH header + * with signature information for the packet + */ +#define AH_FLAG 0x10 + +/* + * The length of the AH struct must be 44 bytes. + */ +#define EXPECTED_AH_HDRLEN 44 + +typedef struct +{ + u8 nh; // To match with reserved in IPSEC AH + // Length of the signature field. Note that the signature might be smaller + // than the field: the actual size is computed from the field size and + // signaturePadding. + u8 payloadlen; + union + { + u16 reserved; + + struct + { + u8 validationAlgorithm; + u8 signaturePadding; + }; + }; + union + { + struct + { + u32 spi; + u32 seq; + }; + // Unix timestamp indicating when the signature has been calculated + u8 timestamp_as_u8[8]; + u16 timestamp_as_u16[4]; + u32 timestamp_as_u32[2]; + }; + // ICV would follow + u8 keyId[32]; // Hash of pub key + /* 44 B + validationPayload */ + u8 validationPayload[0]; // Holds the signature +} _ah_header_t; + +#define AH_HDRLEN sizeof (_ah_header_t) +static_assert (EXPECTED_AH_HDRLEN == AH_HDRLEN, + "Size of AH Struct does not match its expected size."); + +#endif /* HICN_PROTOCOL_AH_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/icmp.c b/lib/src/protocol/icmp.c index 1fc6c7d2f..71417a4e0 100644 --- a/lib/src/protocol/icmp.c +++ b/lib/src/protocol/icmp.c @@ -13,10 +13,11 @@ * limitations under the License. */ -#include <string.h> -#include <hicn/protocol/icmp.h> #include <hicn/error.h> -#include <hicn/ops.h> +#include <string.h> + +#include "icmp.h" +#include "../ops.h" DECLARE_get_interest_locator (icmp, UNEXPECTED); DECLARE_set_interest_locator (icmp, UNEXPECTED); @@ -24,89 +25,110 @@ DECLARE_get_interest_name (icmp, UNEXPECTED); DECLARE_set_interest_name (icmp, UNEXPECTED); DECLARE_get_interest_name_suffix (icmp, UNEXPECTED); DECLARE_set_interest_name_suffix (icmp, UNEXPECTED); -DECLARE_is_interest (icmp, UNEXPECTED); -DECLARE_mark_packet_as_interest (icmp, UNEXPECTED); -DECLARE_mark_packet_as_data (icmp, UNEXPECTED); DECLARE_get_data_locator (icmp, UNEXPECTED); DECLARE_set_data_locator (icmp, UNEXPECTED); DECLARE_get_data_name (icmp, UNEXPECTED); DECLARE_set_data_name (icmp, UNEXPECTED); DECLARE_get_data_name_suffix (icmp, UNEXPECTED); DECLARE_set_data_name_suffix (icmp, UNEXPECTED); -DECLARE_get_data_pathlabel (icmp, UNEXPECTED); -DECLARE_set_data_pathlabel (icmp, UNEXPECTED); -DECLARE_update_data_pathlabel (icmp, UNEXPECTED); +DECLARE_get_data_path_label (icmp, UNEXPECTED); +DECLARE_set_data_path_label (icmp, UNEXPECTED); +DECLARE_update_data_path_label (icmp, UNEXPECTED); DECLARE_get_lifetime (icmp, UNEXPECTED); DECLARE_set_lifetime (icmp, UNEXPECTED); -DECLARE_get_source_port (icmp, UNEXPECTED); -DECLARE_get_dest_port (icmp, UNEXPECTED); -DECLARE_set_source_port (icmp, UNEXPECTED); -DECLARE_set_dest_port (icmp, UNEXPECTED); -DECLARE_get_length (icmp, UNEXPECTED); -DECLARE_get_payload_length (icmp, UNEXPECTED); -DECLARE_set_payload_length (icmp, UNEXPECTED); +// DECLARE_get_payload_len (icmp, UNEXPECTED); +DECLARE_set_payload_len (icmp, UNEXPECTED); DECLARE_get_payload_type (icmp, UNEXPECTED); DECLARE_set_payload_type (icmp, UNEXPECTED); DECLARE_get_signature (icmp, UNEXPECTED); +DECLARE_has_signature (icmp, UNEXPECTED); DECLARE_is_last_data (icmp, UNEXPECTED); DECLARE_set_last_data (icmp, UNEXPECTED); +DECLARE_get_ttl (icmp, UNEXPECTED); +DECLARE_set_ttl (icmp, UNEXPECTED); +DECLARE_get_src_port (icmp, UNEXPECTED); +DECLARE_set_src_port (icmp, UNEXPECTED); +DECLARE_get_dst_port (icmp, UNEXPECTED); +DECLARE_set_dst_port (icmp, UNEXPECTED); int -icmp_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +icmp_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - h->icmp = (_icmp_header_t){ + pkbuf->icmp = pkbuf->len; + if (ICMP_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += ICMP_HDRLEN; + + _icmp_header_t *icmp = pkbuf_get_icmp (pkbuf); + + *icmp = (_icmp_header_t){ .type = 0, .code = 0, .csum = 0, }; - return HICN_LIB_ERROR_NONE; // CHILD_OPS(init_packet_header, type, h->icmp); + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -icmp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) +icmp_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - h->icmp.csum = 0; + _icmp_header_t *icmp = pkbuf_get_icmp (pkbuf); + + icmp->csum = 0; - return CHILD_OPS (reset_interest_for_hash, type, h); + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -icmp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +icmp_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - h->icmp.csum = 0; + _icmp_header_t *icmp = pkbuf_get_icmp (pkbuf); + + icmp->csum = 0; - return CHILD_OPS (reset_data_for_hash, type, h); + return CALL_CHILD (reset_data_for_hash, pkbuf, pos); } int -icmp_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +icmp_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { return HICN_LIB_ERROR_NOT_IMPLEMENTED; - // h->icmp.csum = 0; - // h->icmp.csum = csum(h->bytes, TCP_HDRLEN + payload_length, + // icmp->csum = 0; + // icmp->csum = csum(h->bytes, TCP_HDRLEN + payload_len, // ~partial_csum); // - // return CHILD_OPS(update_checksums, type, h->icmp, 0, payload_length); + // return CALL_CHILD(update_checksums, pkbuf, pos->icmp, 0, + // payload_len); } int -icmp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +icmp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first) { return HICN_LIB_ERROR_NOT_IMPLEMENTED; - // if (csum(h->bytes, TCP_HDRLEN + payload_length, ~partial_csum) != 0) +} + +int +icmp_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) +{ + return HICN_LIB_ERROR_NOT_IMPLEMENTED; + // if (csum(h->bytes, TCP_HDRLEN + payload_len, ~partial_csum) != 0) // return HICN_LIB_ERROR_CORRUPTED_PACKET; - // return CHILD_OPS(verify_checksums, type, h->icmp, 0, payload_length); + // return CALL_CHILD(verify_checksums, pkbuf, pos->icmp, 0, + // payload_len); } int -icmp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +icmp_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { return HICN_LIB_ERROR_NOT_IMPLEMENTED; - // u16 *icmp_checksum = &(h->icmp.csum); + // u16 *icmp_checksum = &(icmp->csum); // // /* // * Padding fields are set to zero so we can apply checksum on the @@ -127,12 +149,13 @@ icmp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, } int -icmp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +icmp_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { return HICN_LIB_ERROR_NOT_IMPLEMENTED; - // u16 *icmp_checksum = &(h->icmp.csum); + // u16 *icmp_checksum = &(icmp->csum); // // /* // * Padding fields are set to zero so we can apply checksum on the @@ -147,9 +170,9 @@ icmp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, // csum = ip_csum_add_even (csum, addr_new->ip6.as_u64[0]); // csum = ip_csum_add_even (csum, addr_new->ip6.as_u64[1]); // - // csum = ip_csum_sub_even (csum, h->icmp.pathlabel); - // icmp_update_data_pathlabel(type, h, face_id); - // csum = ip_csum_add_even (csum, h->icmp.pathlabel); + // csum = ip_csum_sub_even (csum, icmp->path_label); + // icmp_update_data_path_label(pkbuf, pos, face_id); + // csum = ip_csum_add_even (csum, icmp->path_label); // // *icmp_checksum = ip_csum_fold (csum); // @@ -157,96 +180,92 @@ icmp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, } int -icmp_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +icmp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type) { - *header_length = ICMP_HDRLEN; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (get_type, pkbuf, pos, type); } int -icmp_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +icmp_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - - *header_length = ICMP_HDRLEN + child_header_length; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_type, pkbuf, pos, type); } int -icmp_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, +icmp_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *signature_size) { - return CHILD_OPS (get_signature_size, type, h, signature_size); + return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size); } int -icmp_set_signature_size (hicn_type_t type, hicn_protocol_t *h, +icmp_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t signature_size) { - return CHILD_OPS (set_signature_size, type, h, signature_size); + return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size); } int -icmp_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, +icmp_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t padding) { - return CHILD_OPS (set_signature_padding, type, h, padding); + return CALL_CHILD (set_signature_padding, pkbuf, pos, padding); } int -icmp_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, +icmp_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *padding) { - return CHILD_OPS (get_signature_padding, type, h, padding); + return CALL_CHILD (get_signature_padding, pkbuf, pos, padding); } int -icmp_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, +icmp_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t signature_timestamp) { - return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp); } int -icmp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, +icmp_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t *signature_timestamp) { - return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp); } int -icmp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, +icmp_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t validation_algorithm) { - return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (set_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -icmp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, +icmp_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *validation_algorithm) { - return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (get_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -icmp_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +icmp_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *key_id, size_t key_len) { - return CHILD_OPS (set_key_id, type, h, key_id); + return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len); } int -icmp_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size) +icmp_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **key_id, uint8_t *key_id_size) { - return CHILD_OPS (get_key_id, type, h, key_id, key_id_size); + return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size); } -DECLARE_HICN_OPS (icmp); +DECLARE_HICN_OPS (icmp, ICMP_HDRLEN); /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/protocol/icmp.h b/lib/src/protocol/icmp.h new file mode 100644 index 000000000..6cbba6398 --- /dev/null +++ b/lib/src/protocol/icmp.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file protocol/icmp.h + * @brief ICMP packet header + */ +#ifndef HICN_PROTOCOL_ICMP_H +#define HICN_PROTOCOL_ICMP_H + +#include <hicn/common.h> + +/* + * The length of the ICMP header struct must be 4 bytes. + */ +#define EXPECTED_ICMP_HDRLEN 4 + +typedef struct +{ + u8 type; + u8 code; + u16 csum; +} _icmp_header_t; + +#define ICMP_HDRLEN sizeof (_icmp_header_t) +static_assert (EXPECTED_ICMP_HDRLEN == ICMP_HDRLEN, + "Size of ICMP struct does not match its expected size."); + +/* + * The length of the ICMPWLDR header struct must be 4 bytes. + */ +#define EXPECTED_ICMPWLDR_HDRLEN 8 + +typedef struct +{ + u8 type; + u8 code; + u16 csum; + union + { + struct + { + u16 id; + u16 sequence; + } echo; /* echo datagram */ + u32 gateway; /* gateway address */ + struct + { + u16 _unused; + u16 mtu; + } frag; /* path mtu discovery */ + struct + { + u16 expected_lbl; + u16 received_lbl; + } wldr_notification_lbl; + }; +} _icmp_wldr_header_t; + +#define ICMPWLDR_HDRLEN sizeof (_icmp_wldr_header_t) +static_assert (EXPECTED_ICMPWLDR_HDRLEN == ICMPWLDR_HDRLEN, + "Size of ICMPWLDR struct does not match its expected size."); + +#endif /* HICN_PROTOCOL_ICMP_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/icmprd.h b/lib/src/protocol/icmprd.h new file mode 100644 index 000000000..7edff8111 --- /dev/null +++ b/lib/src/protocol/icmprd.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file protocol/icmp-rd.c + * @brief hICN operations for ICMP Redirect header + */ +#ifndef HICN_PROTOCOL_ICMPRD_H +#define HICN_PROTOCOL_ICMPRD_H + +#include <hicn/common.h> +#include "ipv4.h" + +/* + * The length of the ICMPRD4 header struct must be 92 bytes. + */ +#define EXPECTED_ICMPRD4_HDRLEN 92 + +typedef struct +{ + u8 type; + u8 code; + u16 csum; + ipv4_address_t ip; + _ipv4_header_t iph; + u8 data[64]; +} _icmprd4_header_t; + +#define ICMPRD4_HDRLEN sizeof (_icmprd4_header_t) +static_assert (EXPECTED_ICMPRD4_HDRLEN == ICMPRD4_HDRLEN, + "Size of ICMPWLDR struct does not match its expected size."); + +/* + * The length of the ICMPRD header struct must be 40 bytes. + */ +#define EXPECTED_ICMPRD_HDRLEN 40 + +typedef struct +{ + u8 type; + u8 code; + u16 csum; + u32 res; + ipv6_address_t tgt; + ipv6_address_t dst; +} _icmprd_header_t; + +#define ICMPRD_HDRLEN sizeof (_icmprd_header_t) +static_assert (EXPECTED_ICMPRD_HDRLEN == ICMPRD_HDRLEN, + "Size of ICMPWLDR struct does not match its expected size."); + +#endif /* HICN_PROTOCOL_ICMPRD_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/ipv4.c b/lib/src/protocol/ipv4.c index 840fbe34b..a13728d04 100644 --- a/lib/src/protocol/ipv4.c +++ b/lib/src/protocol/ipv4.c @@ -14,7 +14,7 @@ */ /** - * @file protocol/ipv4.c + * @file protocol/ipv4->c * @brief hICN operations for IPv4 header * * NOTE: IPv4 options (affecting the header size) are currently not supported. @@ -28,264 +28,262 @@ #include <string.h> #include <hicn/error.h> -#include <hicn/ops.h> #include <hicn/common.h> -#include <hicn/header.h> -#include <hicn/protocol/ipv4.h> -typedef unsigned short u_short; -int ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *payload_length); +#include "../ops.h" +#include "ipv4.h" + +#define UINT16_T_MASK 0x0000ffff // 1111 1111 1111 1111 + +#define ipv4_get_payload_len(pkbuf, ipv4) htons (ipv4->len - pkbuf->payload) int -ipv4_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +ipv4_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - size_t total_header_length; - int rc = - hicn_ops_vft[type.l1]->get_header_length (type, h, &total_header_length); - if (rc < 0) - return rc; + assert (pkbuf->len == 0); + if (IPV4_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += IPV4_HDRLEN; + + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + hicn_packet_format_t format = hicn_packet_get_format (pkbuf); - h->ipv4 = (_ipv4_header_t){ + size_t header_len; + hicn_packet_get_header_length_from_format (pkbuf->format, &header_len); + + /* We initialize the len considering an empty payload */ + *ipv4 = (_ipv4_header_t){ .version_ihl = (IPV4_DEFAULT_VERSION << 4) | (0x0f & IPV4_DEFAULT_IHL), .tos = IPV4_DEFAULT_TOS, - .len = htons ((u16) total_header_length), + .len = htons (header_len), .id = htons (IPV4_DEFAULT_ID), .frag_off = htons (IPV4_DEFAULT_FRAG_OFF), .ttl = HICN_DEFAULT_TTL, - .protocol = type.l2, + .protocol = format.as_u8[pos + 1], .csum = 0, .saddr.as_u32 = 0, .daddr.as_u32 = 0, }; - return CHILD_OPS (init_packet_header, type, h); + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -ipv4_get_interest_locator (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address) +ipv4_get_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_ip_address_t *ip_address) { - ip_address->v4 = h->ipv4.saddr; + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ip_address->v4 = ipv4->saddr; return HICN_LIB_ERROR_NONE; } int -ipv4_set_interest_locator (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address) +ipv4_set_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address) { - h->ipv4.saddr = ip_address->v4; + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ipv4->saddr = ip_address->v4; return HICN_LIB_ERROR_NONE; } int -ipv4_get_interest_name (hicn_type_t type, const hicn_protocol_t *h, +ipv4_get_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_t *name) { - name->prefix.v4 = h->ipv4.daddr; - return CHILD_OPS (get_interest_name_suffix, type, h, &(name->suffix)); + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + name->prefix.v4 = ipv4->daddr; + return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv4_set_interest_name (hicn_type_t type, hicn_protocol_t *h, +ipv4_set_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_t *name) { - h->ipv4.daddr = name->prefix.v4; - return CHILD_OPS (set_interest_name_suffix, type, h, &(name->suffix)); + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ipv4->daddr = name->prefix.v4; + return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv4_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +ipv4_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - return CHILD_OPS (get_interest_name_suffix, type, h, suffix); + return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, suffix); } int -ipv4_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h, +ipv4_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - return CHILD_OPS (set_interest_name_suffix, type, h, suffix); + return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, suffix); } int -ipv4_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest) +ipv4_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type) { - return CHILD_OPS (is_interest, type, h, is_interest); + return CALL_CHILD (get_type, pkbuf, pos, type); } int -ipv4_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h) +ipv4_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type) { - return CHILD_OPS (mark_packet_as_interest, type, h); + return CALL_CHILD (set_type, pkbuf, pos, type); } int -ipv4_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) +ipv4_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - return CHILD_OPS (mark_packet_as_data, type, h); -} + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); -int -ipv4_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) -{ /* Sets everything to 0 up to IP destination address */ - memset (&(h->ipv4), 0, 16); + memset (ipv4, 0, 16); - return CHILD_OPS (reset_interest_for_hash, type, h); + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -ipv4_get_data_locator (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address) +ipv4_get_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_ip_address_t *ip_address) { - ip_address->v4 = h->ipv4.daddr; + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ip_address->v4 = ipv4->daddr; return HICN_LIB_ERROR_NONE; } int -ipv4_set_data_locator (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address) +ipv4_set_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address) { - h->ipv4.daddr = ip_address->v4; + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ipv4->daddr = ip_address->v4; return HICN_LIB_ERROR_NONE; } int -ipv4_get_data_name (hicn_type_t type, const hicn_protocol_t *h, +ipv4_get_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_t *name) { - name->prefix.v4 = h->ipv4.saddr; - return CHILD_OPS (get_data_name_suffix, type, h, &(name->suffix)); + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + name->prefix.v4 = ipv4->saddr; + return CALL_CHILD (get_data_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv4_set_data_name (hicn_type_t type, hicn_protocol_t *h, +ipv4_set_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_t *name) { - h->ipv4.saddr = name->prefix.v4; - return CHILD_OPS (set_data_name_suffix, type, h, &(name->suffix)); + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ipv4->saddr = name->prefix.v4; + return CALL_CHILD (set_data_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv4_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +ipv4_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - return CHILD_OPS (get_data_name_suffix, type, h, suffix); + return CALL_CHILD (get_data_name_suffix, pkbuf, pos, suffix); } int -ipv4_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, +ipv4_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - return CHILD_OPS (set_data_name_suffix, type, h, suffix); + return CALL_CHILD (set_data_name_suffix, pkbuf, pos, suffix); } int -ipv4_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h, - u32 *pathlabel) +ipv4_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t *path_label) { - return CHILD_OPS (get_data_pathlabel, type, h, pathlabel); + return CALL_CHILD (get_data_path_label, pkbuf, pos, path_label); } int -ipv4_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const u32 pathlabel) +ipv4_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t path_label) { - return CHILD_OPS (set_data_pathlabel, type, h, pathlabel); + return CALL_CHILD (set_data_path_label, pkbuf, pos, path_label); } int -ipv4_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const hicn_faceid_t face_id) +ipv4_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_faceid_t face_id) { - return CHILD_OPS (update_data_pathlabel, type, h, face_id); + return CALL_CHILD (update_data_path_label, pkbuf, pos, face_id); } int -ipv4_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +ipv4_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + /* Sets everything to 0 up to source address */ - memset (&h->ipv4, 0, 12); + memset (ipv4, 0, 12); /* Clears destination address */ - memset (&(h->ipv4.daddr), 0, 4); + memset (&(ipv4->daddr), 0, 4); - return CHILD_OPS (reset_data_for_hash, type, h); + return CALL_CHILD (reset_data_for_hash, pkbuf, pos); } int -ipv4_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, +ipv4_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_lifetime_t *lifetime) { - return CHILD_OPS (get_lifetime, type, h, lifetime); + return CALL_CHILD (get_lifetime, pkbuf, pos, lifetime); } int -ipv4_set_lifetime (hicn_type_t type, hicn_protocol_t *h, +ipv4_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_lifetime_t lifetime) { - return CHILD_OPS (set_lifetime, type, h, lifetime); -} - -int -ipv4_get_source_port (hicn_type_t type, const hicn_protocol_t *h, - u16 *source_port) -{ - return CHILD_OPS (get_source_port, type, h, source_port); -} - -int -ipv4_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port) -{ - return CHILD_OPS (get_dest_port, type, h, dest_port); -} - -int -ipv4_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port) -{ - return CHILD_OPS (set_source_port, type, h, source_port); + return CALL_CHILD (set_lifetime, pkbuf, pos, lifetime); } int -ipv4_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port) +ipv4_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - return CHILD_OPS (set_dest_port, type, h, dest_port); -} + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); -int -ipv4_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) -{ /* * Checksum field is not accounted for in lower layers, so we can compute * them in any order. Note that it is only a header checksum. */ - h->ipv4.csum = 0; - h->ipv4.csum = csum (h, IPV4_HDRLEN, 0); + ipv4->csum = 0; + ipv4->csum = csum (pkbuf_get_header (pkbuf), IPV4_HDRLEN, 0); - /* Retrieve payload length if not specified, as it is not available later */ - if (payload_length == 0) + /* Retrieve payload len if not specified, as it is not available later */ + if (payload_len == 0) { - int rc = ipv4_get_payload_length (type, h, &payload_length); - if (rc < 0) - return rc; + payload_len = ipv4_get_payload_len (pkbuf, ipv4); } - /* Ignore the payload if payload_length = ~0 */ - if (payload_length == ~0) + /* Ignore the payload if payload_len = ~0 */ + if (payload_len == ~0) { - payload_length = 0; + payload_len = 0; } /* Build pseudo-header */ ipv4_pseudo_header_t psh; - psh.ip_src = h->ipv4.saddr; - psh.ip_dst = h->ipv4.daddr; + psh.ip_src = ipv4->saddr; + psh.ip_dst = ipv4->daddr; /* Size is u32 and not u16, we cannot copy and need to care about endianness */ - psh.size = htons (ntohs (h->ipv4.len) - (u16) IPV4_HDRLEN); + psh.size = htons (ntohs (ipv4->len) - (u16) IPV4_HDRLEN); psh.zero = 0; - psh.protocol = (u8) h->ipv4.protocol; + psh.protocol = (u8) ipv4->protocol; /* Compute partial checksum based on pseudo-header */ if (partial_csum != 0) @@ -294,243 +292,289 @@ ipv4_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, } partial_csum = csum (&psh, IPV4_PSHDRLEN, partial_csum); - return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length); + return CALL_CHILD (update_checksums, pkbuf, pos, partial_csum, payload_len); +} + +int +ipv4_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first) +{ + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + /* We update the child first */ + int rc = CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val, + new_val, size, false); + if (rc < 0) + return rc; + + if (!skip_first) + { + for (uint8_t i = 0; i < size; i++) + { + uint16_t old_csum = ~ipv4->csum; + uint16_t not_old_val = ~(*old_val); + uint32_t sum = (uint32_t) old_csum + not_old_val + *new_val; + + while (sum >> 16) + { + sum = (sum >> 16) + (sum & UINT16_T_MASK); + } + + ipv4->csum = ~sum; + ++old_val; + ++new_val; + } + } + + return HICN_LIB_ERROR_NONE; } int -ipv4_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +ipv4_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + /* * Checksum field is not accounted for in lower layers, so we can compute * them in any order. Note that it is only a header checksum. */ - if (csum (h, IPV4_HDRLEN, 0) != 0) + if (csum (pkbuf_get_header (pkbuf), IPV4_HDRLEN, 0) != 0) return HICN_LIB_ERROR_CORRUPTED_PACKET; - /* Retrieve payload length if not specified, as it is not available later */ - if (payload_length == 0) + /* Retrieve payload len if not specified, as it is not available later */ + if (payload_len == 0) { - int rc = ipv4_get_payload_length (type, h, &payload_length); - if (rc < 0) - return rc; + payload_len = ipv4_get_payload_len (pkbuf, ipv4); } /* Build pseudo-header */ ipv4_pseudo_header_t psh; - psh.ip_src = h->ipv4.saddr; - psh.ip_dst = h->ipv4.daddr; + psh.ip_src = ipv4->saddr; + psh.ip_dst = ipv4->daddr; /* Size is u32 and not u16, we cannot copy and need to care about endianness */ - psh.size = htons (ntohs (h->ipv4.len) - (u16) IPV4_HDRLEN); + psh.size = htons (ntohs (ipv4->len) - (u16) IPV4_HDRLEN); psh.zero = 0; - psh.protocol = (u8) h->ipv4.protocol; + psh.protocol = (u8) ipv4->protocol; /* Compute partial checksum based on pseudo-header */ partial_csum = csum (&psh, IPV4_PSHDRLEN, 0); - return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length); + return CALL_CHILD (verify_checksums, pkbuf, pos, partial_csum, payload_len); } int -ipv4_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +ipv4_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + // ASSERT(addr_old == NULL); - addr_old->v4 = h->ipv4.saddr; + addr_old->v4 = ipv4->saddr; addr_old->pad[0] = 0; addr_old->pad[1] = 0; addr_old->pad[2] = 0; - h->ipv4.saddr = addr_new->v4; - h->ipv4.csum = 0; - h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0); + ipv4->saddr = addr_new->v4; + ipv4->csum = 0; + ipv4->csum = csum (&ipv4, IPV4_HDRLEN, 0); - return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old); + return CALL_CHILD (rewrite_interest, pkbuf, pos, addr_new, addr_old); } int -ipv4_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +ipv4_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + // ASSERT(addr_old == NULL); - addr_old->v4 = h->ipv4.daddr; + addr_old->v4 = ipv4->daddr; addr_old->pad[0] = 0; addr_old->pad[1] = 0; addr_old->pad[2] = 0; - h->ipv4.daddr = addr_new->v4; - h->ipv4.csum = 0; - h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0); + ipv4->daddr = addr_new->v4; + ipv4->csum = 0; + ipv4->csum = csum (&ipv4, IPV4_HDRLEN, 0); - return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id, - reset_pl); + return CALL_CHILD (rewrite_data, pkbuf, pos, addr_new, addr_old, face_id, + reset_pl); } int -ipv4_get_current_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv4_set_payload_len (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t payload_len) { - *header_length = IPV4_HDRLEN; + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + size_t child_header_len = hicn_ops_vft[pos + 1]->header_len; + + ipv4->len = htons ((u16) (payload_len + IPV4_HDRLEN + child_header_len)); return HICN_LIB_ERROR_NONE; } int -ipv4_get_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv4_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t *payload_type) { - *header_length = h->ipv4.len; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (get_payload_type, pkbuf, pos, payload_type); } int -ipv4_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv4_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t payload_type) { - *header_length = IPV4_HDRLEN; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_payload_type, pkbuf, pos, payload_type); } int -ipv4_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv4_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t *signature_size) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *header_length = IPV4_HDRLEN + child_header_length; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size); } int -ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *payload_length) +ipv4_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t signature_size) { - size_t child_header_length; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *payload_length = htons (h->ipv4.len) - IPV4_HDRLEN - child_header_length; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size); } int -ipv4_set_payload_length (hicn_type_t type, hicn_protocol_t *h, - size_t payload_length) +ipv4_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t padding) { - size_t child_header_length; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - h->ipv4.len = - htons ((u_short) (payload_length + IPV4_HDRLEN + child_header_length)); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_signature_padding, pkbuf, pos, padding); } int -ipv4_get_payload_type (hicn_type_t type, const hicn_protocol_t *h, - hicn_payload_type_t *payload_type) +ipv4_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t *padding) { - return CHILD_OPS (get_payload_type, type, h, payload_type); + return CALL_CHILD (get_signature_padding, pkbuf, pos, padding); } int -ipv4_set_payload_type (hicn_type_t type, hicn_protocol_t *h, - hicn_payload_type_t payload_type) +ipv4_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint64_t signature_timestamp) { - return CHILD_OPS (set_payload_type, type, h, payload_type); + return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp); } int -ipv4_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, - size_t *signature_size) +ipv4_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint64_t *signature_timestamp) { - return CHILD_OPS (get_signature_size, type, h, signature_size); + return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp); } int -ipv4_set_signature_size (hicn_type_t type, hicn_protocol_t *h, - size_t signature_size) +ipv4_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t validation_algorithm) { - return CHILD_OPS (set_signature_size, type, h, signature_size); + return CALL_CHILD (set_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -ipv4_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, - size_t padding) +ipv4_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *validation_algorithm) { - return CHILD_OPS (set_signature_padding, type, h, padding); + return CALL_CHILD (get_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -ipv4_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, - size_t *padding) +ipv4_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *key_id, size_t key_len) { - return CHILD_OPS (get_signature_padding, type, h, padding); + return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len); } int -ipv4_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, - uint64_t signature_timestamp) +ipv4_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **key_id, uint8_t *key_id_size) { - return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size); } int -ipv4_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, - uint64_t *signature_timestamp) +ipv4_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **signature) { - return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_signature, pkbuf, pos, signature); } int -ipv4_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, - uint8_t validation_algorithm) +ipv4_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag) { - return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (has_signature, pkbuf, pos, flag); } int -ipv4_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, - uint8_t *validation_algorithm) +ipv4_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last) +{ + return CALL_CHILD (is_last_data, pkbuf, pos, is_last); +} + +int +ipv4_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos) +{ + return CALL_CHILD (set_last_data, pkbuf, pos); +} + +int +ipv4_get_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 *hops) { - return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm); + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + *hops = ipv4->ttl; + + return HICN_LIB_ERROR_NONE; } int -ipv4_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +ipv4_set_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 hops) { - return CHILD_OPS (set_key_id, type, h, key_id); + _ipv4_header_t *ipv4 = pkbuf_get_ipv4 (pkbuf); + + ipv4->ttl = hops; + + return HICN_LIB_ERROR_NONE; } int -ipv4_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size) +ipv4_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - return CHILD_OPS (get_key_id, type, h, key_id, key_id_size); + return CALL_CHILD (get_src_port, pkbuf, pos, port); } int -ipv4_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature) +ipv4_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - return CHILD_OPS (get_signature, type, h, signature); + return CALL_CHILD (set_src_port, pkbuf, pos, port); } int -ipv4_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last) +ipv4_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - return CHILD_OPS (is_last_data, type, h, is_last); + return CALL_CHILD (get_dst_port, pkbuf, pos, port); } int -ipv4_set_last_data (hicn_type_t type, hicn_protocol_t *h) +ipv4_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - return CHILD_OPS (set_last_data, type, h); + return CALL_CHILD (set_dst_port, pkbuf, pos, port); } -DECLARE_HICN_OPS (ipv4); +DECLARE_HICN_OPS (ipv4, IPV4_HDRLEN); /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/protocol/ipv4.h b/lib/src/protocol/ipv4.h new file mode 100644 index 000000000..5d729b955 --- /dev/null +++ b/lib/src/protocol/ipv4.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HICN_PROTOCOL_IPV4 +#define HICN_PROTOCOL_IPV4 + +#include <hicn/util/ip_address.h> + +#include <hicn/base.h> +#include <hicn/common.h> + +/* Headers were adapted from linux' definitions in netinet/ip.h */ + +/* + * The length of the IPV4 header struct must be 20 bytes. + */ +#define EXPECTED_IPV4_HDRLEN 20 + +typedef struct +{ + union + { + struct + { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + u8 ihl : 4; + u8 version : 4; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8 version : 4; + u8 ihl : 4; +#else +#error "Unsupported endianness" +#endif + }; + + u8 version_ihl; + }; + u8 tos; + + /* + * This is the total length of the IP packet, including the IP header. + * NOTE: vriable len header size is currently not supported by the lib. + */ + u16 len; + + u16 id; + u16 frag_off; + u8 ttl; + u8 protocol; + u16 csum; + ipv4_address_t saddr; + ipv4_address_t daddr; +} _ipv4_header_t; + +#define ipv4_header_bytes(ipv4_header) \ + (sizeof (u32) * (ipv4_header->version_ihl & 0xf)) + +#define IPV4_HDRLEN sizeof (_ipv4_header_t) +static_assert (EXPECTED_IPV4_HDRLEN == IPV4_HDRLEN, + "Size of IPV4 struct does not match its expected size."); + +/* + * The length of the IPV4 pseudo header struct must be 12 bytes. + */ +#define EXPECTED_IPV4_PSHDRLEN 12 + +typedef struct +{ + ipv4_address_t ip_src; + ipv4_address_t ip_dst; + u8 zero; + u8 protocol; + u16 size; +} ipv4_pseudo_header_t; + +#define IPV4_PSHDRLEN sizeof (ipv4_pseudo_header_t) +static_assert (EXPECTED_IPV4_PSHDRLEN == IPV4_PSHDRLEN, + "Size of IPV4_PSHDR struct does not match its expected size."); + +/* Default field values */ +#define IPV4_DEFAULT_VERSION 4 +#define IPV4_DEFAULT_IHL 5 +#define IPV4_DEFAULT_TOS 0 +#define IPV4_DEFAULT_PAYLOAD_LENGTH 0 +#define IPV4_DEFAULT_ID 300 +#define IPV4_DEFAULT_FRAG_OFF 0x000 +#define IPV4_DEFAULT_TTL 64 +#define IPV4_DEFAULT_PROTOCOL IPPROTO_TCP +#define IPV4_DEFAULT_SRC_IP 0, 0, 0, 0 +#define IPV4_DEFAULT_DST_IP 0, 0, 0, 0 + +#endif /* HICN_PROTOCOL_IPV4 */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/ipv6.c b/lib/src/protocol/ipv6.c index b3c543249..aec521afc 100644 --- a/lib/src/protocol/ipv6.c +++ b/lib/src/protocol/ipv6.c @@ -17,247 +17,252 @@ #include <string.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/ops.h> + +#include "ipv6.h" +#include "../ops.h" typedef unsigned short u_short; -int ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *payload_length); + +#ifdef OPAQUE_IP +#define GET_IPV6_HEADER(pkbuf) \ + (_ipv6_header_t *) ((pkbuf)->header + (pkbuf)->ipv6) +#else +#define GET_IPV6_HEADER(pkbuf) (_ipv6_header_t *) ((pkbuf)->header) +#endif /* OPAQUE_IP */ int -ipv6_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +ipv6_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - size_t total_header_length; - int rc = CHILD_OPS (get_header_length, type, h, &total_header_length); - if (rc < 0) - return rc; + assert (pkbuf->len == 0); + if (IPV6_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += IPV6_HDRLEN; + + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); - /* *INDENT-OFF* */ - h->ipv6 = (_ipv6_header_t){ + hicn_packet_format_t format = hicn_packet_get_format (pkbuf); + + size_t header_len; + hicn_packet_get_header_length_from_format (pkbuf->format, &header_len); + + /* clang-format off */ + *ipv6 = (_ipv6_header_t){ .saddr = IP6_ADDRESS_EMPTY, .daddr = IP6_ADDRESS_EMPTY, .version_class_flow = htonl ((IPV6_DEFAULT_VERSION << 28) | (IPV6_DEFAULT_TRAFFIC_CLASS << 20) | (IPV6_DEFAULT_FLOW_LABEL & 0xfffff)), - .len = htons ((u16) total_header_length), - .nxt = type.l2, + .len = htons(header_len - IPV6_HDRLEN), + .nxt = format.as_u8[pos + 1], .hlim = HICN_DEFAULT_TTL, }; - /* *INDENT-ON* */ - return CHILD_OPS (init_packet_header, type, h); + /* clang-format on */ + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -ipv6_get_interest_locator (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address) +ipv6_get_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_ip_address_t *ip_address) { - ip_address->v6 = h->ipv6.saddr; + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ip_address->v6 = ipv6->saddr; return HICN_LIB_ERROR_NONE; } int -ipv6_set_interest_locator (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address) +ipv6_set_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address) { - h->ipv6.saddr = ip_address->v6; + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ipv6->saddr = ip_address->v6; return HICN_LIB_ERROR_NONE; } int -ipv6_get_interest_name (hicn_type_t type, const hicn_protocol_t *h, +ipv6_get_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_t *name) { - name->prefix.v6 = h->ipv6.daddr; - return CHILD_OPS (get_interest_name_suffix, type, h, &(name->suffix)); + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + name->prefix.v6 = ipv6->daddr; + return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv6_set_interest_name (hicn_type_t type, hicn_protocol_t *h, +ipv6_set_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_t *name) { - h->ipv6.daddr = name->prefix.v6; - return CHILD_OPS (set_interest_name_suffix, type, h, &(name->suffix)); + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ipv6->daddr = name->prefix.v6; + return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv6_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +ipv6_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - return CHILD_OPS (get_interest_name_suffix, type, h, suffix); + return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, suffix); } int -ipv6_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h, +ipv6_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - return CHILD_OPS (set_interest_name_suffix, type, h, suffix); + return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, suffix); } int -ipv6_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest) +ipv6_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type) { - return CHILD_OPS (is_interest, type, h, is_interest); + return CALL_CHILD (get_type, pkbuf, pos, type); } int -ipv6_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h) +ipv6_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type) { - return CHILD_OPS (mark_packet_as_interest, type, h); + return CALL_CHILD (set_type, pkbuf, pos, type); } int -ipv6_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) +ipv6_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - return CHILD_OPS (mark_packet_as_data, type, h); -} + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); -int -ipv6_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) -{ /* Sets everything to 0 up to IP destination address */ - memset (&(h->ipv6), 0, 24); + memset (ipv6, 0, 24); - return CHILD_OPS (reset_interest_for_hash, type, h); + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -ipv6_get_data_locator (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address) +ipv6_get_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_ip_address_t *ip_address) { - ip_address->v6 = h->ipv6.daddr; + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ip_address->v6 = ipv6->daddr; return HICN_LIB_ERROR_NONE; } int -ipv6_set_data_locator (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address) +ipv6_set_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address) { - h->ipv6.daddr = ip_address->v6; + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ipv6->daddr = ip_address->v6; return HICN_LIB_ERROR_NONE; } int -ipv6_get_data_name (hicn_type_t type, const hicn_protocol_t *h, +ipv6_get_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_t *name) { - name->prefix.v6 = h->ipv6.saddr; - return CHILD_OPS (get_data_name_suffix, type, h, &(name->suffix)); + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + name->prefix.v6 = ipv6->saddr; + return CALL_CHILD (get_data_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv6_set_data_name (hicn_type_t type, hicn_protocol_t *h, +ipv6_set_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_t *name) { - h->ipv6.saddr = name->prefix.v6; - return CHILD_OPS (set_data_name_suffix, type, h, &(name->suffix)); + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ipv6->saddr = name->prefix.v6; + return CALL_CHILD (set_data_name_suffix, pkbuf, pos, &(name->suffix)); } int -ipv6_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +ipv6_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - return CHILD_OPS (get_data_name_suffix, type, h, suffix); + return CALL_CHILD (get_data_name_suffix, pkbuf, pos, suffix); } int -ipv6_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, +ipv6_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - return CHILD_OPS (set_data_name_suffix, type, h, suffix); + return CALL_CHILD (set_data_name_suffix, pkbuf, pos, suffix); } int -ipv6_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h, - u32 *pathlabel) +ipv6_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t *path_label) { - return CHILD_OPS (get_data_pathlabel, type, h, pathlabel); + return CALL_CHILD (get_data_path_label, pkbuf, pos, path_label); } int -ipv6_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const u32 pathlabel) +ipv6_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t path_label) { - return CHILD_OPS (set_data_pathlabel, type, h, pathlabel); + return CALL_CHILD (set_data_path_label, pkbuf, pos, path_label); } int -ipv6_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const hicn_faceid_t face_id) +ipv6_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_faceid_t face_id) { - return CHILD_OPS (update_data_pathlabel, type, h, face_id); + return CALL_CHILD (update_data_path_label, pkbuf, pos, face_id); } int -ipv6_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +ipv6_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + /* IP: Set everithing to 0 up to destination address */ - memset (&h->ipv6, 0, 8); + memset (ipv6, 0, 8); /* Clears destination address */ - memset (&(h->ipv6.daddr), 0, 16); + memset (&(ipv6->daddr), 0, 16); - return CHILD_OPS (reset_data_for_hash, type, h); + return CALL_CHILD (reset_data_for_hash, pkbuf, pos); } int -ipv6_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, +ipv6_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_lifetime_t *lifetime) { - return CHILD_OPS (get_lifetime, type, h, lifetime); + return CALL_CHILD (get_lifetime, pkbuf, pos, lifetime); } int -ipv6_set_lifetime (hicn_type_t type, hicn_protocol_t *h, +ipv6_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_lifetime_t lifetime) { - return CHILD_OPS (set_lifetime, type, h, lifetime); -} - -int -ipv6_get_source_port (hicn_type_t type, const hicn_protocol_t *h, - u16 *source_port) -{ - return CHILD_OPS (get_source_port, type, h, source_port); + return CALL_CHILD (set_lifetime, pkbuf, pos, lifetime); } int -ipv6_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port) +ipv6_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - return CHILD_OPS (get_dest_port, type, h, dest_port); -} - -int -ipv6_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port) -{ - return CHILD_OPS (set_source_port, type, h, source_port); -} + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); -int -ipv6_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port) -{ - return CHILD_OPS (set_dest_port, type, h, dest_port); -} - -int -ipv6_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) -{ - /* Retrieve payload length if not specified */ - if (payload_length == ~0) + /* Retrieve payload len if not specified */ + if (payload_len == ~0) { - int rc = ipv6_get_payload_length (type, h, &payload_length); - if (rc < 0) - return rc; + payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload; } /* Build pseudo-header */ ipv6_pseudo_header_t psh; - psh.ip_src = h->ipv6.saddr; - psh.ip_dst = h->ipv6.daddr; + psh.ip_src = ipv6->saddr; + psh.ip_dst = ipv6->daddr; /* Size is u32 and not u16, we cannot copy and need to care about endianness */ - psh.size = htonl (ntohs (h->ipv6.len)); + psh.size = htonl (ntohs (ipv6->len)); psh.zeros = 0; psh.zero = 0; - psh.protocol = h->ipv6.nxt; + psh.protocol = ipv6->nxt; /* Compute partial checksum based on pseudo-header */ if (partial_csum != 0) @@ -266,31 +271,41 @@ ipv6_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, } partial_csum = csum (&psh, IPV6_PSHDRLEN, partial_csum); - return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length); + return CALL_CHILD (update_checksums, pkbuf, pos, partial_csum, payload_len); } int -ipv6_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +ipv6_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first) { - /* Retrieve payload length if not specified */ - if (payload_length == ~0) + /* We update the child only */ + return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val, + new_val, size, false); +} + +int +ipv6_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) +{ + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + /* Retrieve payload len if not specified */ + if (payload_len == ~0) { - int rc = ipv6_get_payload_length (type, h, &payload_length); - if (rc < 0) - return rc; + payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload; } /* Build pseudo-header */ ipv6_pseudo_header_t pseudo; - pseudo.ip_src = h->ipv6.saddr; - pseudo.ip_dst = h->ipv6.daddr; + pseudo.ip_src = ipv6->saddr; + pseudo.ip_dst = ipv6->daddr; /* Size is u32 and not u16, we cannot copy and need to care about endianness */ - pseudo.size = htonl (ntohs (h->ipv6.len)); + pseudo.size = htonl (ntohs (ipv6->len)); pseudo.zeros = 0; pseudo.zero = 0; - pseudo.protocol = h->ipv6.nxt; + pseudo.protocol = ipv6->nxt; /* Compute partial checksum based on pseudo-header */ if (partial_csum != 0) @@ -299,187 +314,206 @@ ipv6_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, } partial_csum = csum (&pseudo, IPV6_PSHDRLEN, partial_csum); - return CHILD_OPS (verify_checksums, type, h, partial_csum, payload_length); + return CALL_CHILD (verify_checksums, pkbuf, pos, partial_csum, payload_len); } int -ipv6_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +ipv6_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + // ASSERT(addr_old == NULL); - addr_old->v6 = h->ipv6.saddr; - h->ipv6.saddr = addr_new->v6; + addr_old->v6 = ipv6->saddr; + ipv6->saddr = addr_new->v6; - return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old); + return CALL_CHILD (rewrite_interest, pkbuf, pos, addr_new, addr_old); } int -ipv6_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +ipv6_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + // ASSERT(addr_old == NULL); - addr_old->v6 = h->ipv6.daddr; - h->ipv6.daddr = addr_new->v6; + addr_old->v6 = ipv6->daddr; + ipv6->daddr = addr_new->v6; - return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id, - reset_pl); + return CALL_CHILD (rewrite_data, pkbuf, pos, addr_new, addr_old, face_id, + reset_pl); } int -ipv6_get_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv6_set_payload_len (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t payload_len) { - *header_length = IPV6_HDRLEN + ntohs (h->ipv6.len); + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ipv6->len = htons ((u_short) (payload_len + pkbuf->payload - IPV6_HDRLEN)); return HICN_LIB_ERROR_NONE; } int -ipv6_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv6_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t *payload_type) { - *header_length = IPV6_HDRLEN; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (get_payload_type, pkbuf, pos, payload_type); } int -ipv6_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +ipv6_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t payload_type) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *header_length = IPV6_HDRLEN + child_header_length; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_payload_type, pkbuf, pos, payload_type); } int -ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *payload_length) +ipv6_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t *signature_size) { - size_t child_header_length; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *payload_length = ntohs (h->ipv6.len) - child_header_length; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size); } int -ipv6_set_payload_length (hicn_type_t type, hicn_protocol_t *h, - size_t payload_length) +ipv6_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t signature_size) { - size_t child_header_length; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - h->ipv6.len = htons ((u_short) (payload_length + child_header_length)); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size); } int -ipv6_get_payload_type (hicn_type_t type, const hicn_protocol_t *h, - hicn_payload_type_t *payload_type) +ipv6_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t padding) { - return CHILD_OPS (get_payload_type, type, h, payload_type); + return CALL_CHILD (set_signature_padding, pkbuf, pos, padding); } int -ipv6_set_payload_type (hicn_type_t type, hicn_protocol_t *h, - hicn_payload_type_t payload_type) +ipv6_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t *padding) { - return CHILD_OPS (set_payload_type, type, h, payload_type); + return CALL_CHILD (get_signature_padding, pkbuf, pos, padding); } int -ipv6_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, - size_t *signature_size) +ipv6_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint64_t signature_timestamp) { - return CHILD_OPS (get_signature_size, type, h, signature_size); + return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp); } int -ipv6_set_signature_size (hicn_type_t type, hicn_protocol_t *h, - size_t signature_size) +ipv6_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint64_t *signature_timestamp) { - return CHILD_OPS (set_signature_size, type, h, signature_size); + return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp); } int -ipv6_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, - size_t padding) +ipv6_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t validation_algorithm) { - return CHILD_OPS (set_signature_padding, type, h, padding); + return CALL_CHILD (set_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -ipv6_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, - size_t *padding) +ipv6_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *validation_algorithm) { - return CHILD_OPS (get_signature_padding, type, h, padding); + return CALL_CHILD (get_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -ipv6_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, - uint64_t signature_timestamp) +ipv6_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *key_id, size_t key_len) { - return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len); } int -ipv6_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, - uint64_t *signature_timestamp) +ipv6_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **key_id, uint8_t *key_id_size) { - return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size); } int -ipv6_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, - uint8_t validation_algorithm) +ipv6_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **signature) { - return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (get_signature, pkbuf, pos, signature); } int -ipv6_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, - uint8_t *validation_algorithm) +ipv6_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag) +{ + return CALL_CHILD (has_signature, pkbuf, pos, flag); +} + +int +ipv6_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last) +{ + return CALL_CHILD (is_last_data, pkbuf, pos, is_last); +} + +int +ipv6_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos) +{ + return CALL_CHILD (set_last_data, pkbuf, pos); +} + +int +ipv6_get_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 *hops) { - return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm); + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + *hops = ipv6->hlim; + + return HICN_LIB_ERROR_NONE; } int -ipv6_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +ipv6_set_ttl (const hicn_packet_buffer_t *pkbuf, size_t pos, u8 hops) { - return CHILD_OPS (set_key_id, type, h, key_id); + + _ipv6_header_t *ipv6 = pkbuf_get_ipv6 (pkbuf); + + ipv6->hlim = hops; + + return HICN_LIB_ERROR_NONE; } int -ipv6_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size) +ipv6_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - return CHILD_OPS (get_key_id, type, h, key_id, key_id_size); + return CALL_CHILD (get_src_port, pkbuf, pos, port); } int -ipv6_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature) +ipv6_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - return CHILD_OPS (get_signature, type, h, signature); + return CALL_CHILD (set_src_port, pkbuf, pos, port); } int -ipv6_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last) +ipv6_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - return CHILD_OPS (is_last_data, type, h, is_last); + return CALL_CHILD (get_dst_port, pkbuf, pos, port); } int -ipv6_set_last_data (hicn_type_t type, hicn_protocol_t *h) +ipv6_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - return CHILD_OPS (set_last_data, type, h); + return CALL_CHILD (set_dst_port, pkbuf, pos, port); } -DECLARE_HICN_OPS (ipv6); +DECLARE_HICN_OPS (ipv6, IPV6_HDRLEN); /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/protocol/ipv6.h b/lib/src/protocol/ipv6.h new file mode 100644 index 000000000..9a51096a0 --- /dev/null +++ b/lib/src/protocol/ipv6.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HICN_PROTOCOL_IPV6_H +#define HICN_PROTOCOL_IPV6_H + +#include <hicn/util/ip_address.h> + +#include <hicn/common.h> + +/* + * The length of the IPV6 header struct must be 40 bytes. + */ +#define EXPECTED_IPV6_HDRLEN 40 + +typedef struct +{ +#if 0 // TEMPORARY FIX + union + { + struct + { +#endif + u32 version_class_flow; /* version, traffic class and 20 bits of flow-ID */ + u16 len; /* payload length */ + u8 nxt; /* next header */ + u8 hlim; /* hop limit */ +#if 0 + }; + u8 vfc; /* 4 bits version, top 4 bits class */ + }; +#endif + ipv6_address_t saddr; /* source address */ + ipv6_address_t daddr; /* destination address */ +} _ipv6_header_t; + +#define IPV6_HDRLEN sizeof (_ipv6_header_t) +static_assert (EXPECTED_IPV6_HDRLEN == IPV6_HDRLEN, + "Size of IPV6 struct does not match its expected size."); + +/* + * The length of the IPV6 pseudo header struct must be 40 bytes. + */ +#define EXPECTED_IPV6_PSHDRLEN 40 + +typedef struct +{ + ipv6_address_t ip_src; + ipv6_address_t ip_dst; + u32 size; + u16 zeros; + u8 zero; + u8 protocol; +} ipv6_pseudo_header_t; + +#define IPV6_PSHDRLEN sizeof (ipv6_pseudo_header_t) +static_assert (EXPECTED_IPV6_PSHDRLEN == IPV6_PSHDRLEN, + "Size of IPV6_PSHDR struct does not match its expected size."); + +/* Default field values */ +#define IPV6_DEFAULT_VERSION 6 +#define IPV6_DEFAULT_TRAFFIC_CLASS 0 +#define IPV6_DEFAULT_FLOW_LABEL 0 +#define IPV6_DEFAULT_PAYLOAD_LENGTH 0 + +#endif + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/new.c b/lib/src/protocol/new.c index 07c1d0d76..5308e8c0a 100644 --- a/lib/src/protocol/new.c +++ b/lib/src/protocol/new.c @@ -17,423 +17,544 @@ #include <string.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/ops.h> + +#include "udp.h" +#include "../ops.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" -DECLARE_get_source_port (new, UNEXPECTED); -DECLARE_get_dest_port (new, UNEXPECTED); -DECLARE_set_source_port (new, UNEXPECTED); -DECLARE_set_dest_port (new, UNEXPECTED); - -static int -is_interest (u8 flags) -{ - return flags & HICN_NEW_FLAG_INT; -} +DECLARE_get_ttl (new, UNEXPECTED); +DECLARE_set_ttl (new, UNEXPECTED); +DECLARE_get_src_port (new, UNEXPECTED); +DECLARE_set_src_port (new, UNEXPECTED); +DECLARE_get_dst_port (new, UNEXPECTED); +DECLARE_set_dst_port (new, UNEXPECTED); int -new_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +new_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - memset (&h->newhdr, 0, sizeof (h->newhdr)); - _set_new_header_version (&h->newhdr); - uint8_t ah_flag = type.l2 == IPPROTO_AH ? HICN_NEW_FLAG_SIG : 0; - h->newhdr.flags |= ah_flag; + pkbuf->newhdr = pkbuf->len; + if (NEW_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += NEW_HDRLEN; - return CHILD_OPS (init_packet_header, type, h); -} + _new_header_t *new = pkbuf_get_new (pkbuf); -int -new_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest) -{ - *is_interest = (h->newhdr.flags & HICN_NEW_FLAG_INT) != 0; - return HICN_LIB_ERROR_NONE; + hicn_packet_format_t format = hicn_packet_get_format (pkbuf); + + memset (new, 0, sizeof (_new_header_t)); + _set_new_header_version (new); + uint8_t ah_flag = + format.as_u8[pos + 1] == IPPROTO_AH ? HICN_NEW_FLAG_SIG : 0; + new->flags |= ah_flag; + + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -new_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h) +new_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type) { - h->newhdr.flags |= HICN_NEW_FLAG_INT; + _new_header_t *new = pkbuf_get_new (pkbuf); + + /* Interest packets have the INT bit set */ + if (new->flags & HICN_NEW_FLAG_INT) + *type = HICN_PACKET_TYPE_INTEREST; + else + *type = HICN_PACKET_TYPE_DATA; return HICN_LIB_ERROR_NONE; } int -new_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) +new_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type) { - h->newhdr.flags &= ~HICN_NEW_FLAG_INT; + _new_header_t *new = pkbuf_get_new (pkbuf); + + switch (type) + { + case HICN_PACKET_TYPE_INTEREST: + new->flags |= HICN_NEW_FLAG_INT; + break; + case HICN_PACKET_TYPE_DATA: + new->flags &= ~HICN_NEW_FLAG_INT; + break; + default: + return -1; + } return HICN_LIB_ERROR_NONE; } int -new_get_interest_locator (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address) +new_get_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_ip_address_t *ip_address) { - assert (is_interest (h->newhdr.flags)); + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); return HICN_LIB_ERROR_NONE; } int -new_set_interest_locator (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address) +new_set_interest_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address) { - assert (is_interest (h->newhdr.flags)); + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + return HICN_LIB_ERROR_NONE; } int -new_get_interest_name (hicn_type_t type, const hicn_protocol_t *h, +new_get_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_t *name) { - assert (is_interest (h->newhdr.flags)); - name->prefix = h->newhdr.prefix; - name->suffix = ntohl (h->newhdr.suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + + name->prefix = new->prefix; + name->suffix = ntohl (new->suffix); return HICN_LIB_ERROR_NONE; } int -new_set_interest_name (hicn_type_t type, hicn_protocol_t *h, +new_set_interest_name (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_t *name) { - int rc = new_mark_packet_as_interest (type, h); + _new_header_t *new = pkbuf_get_new (pkbuf); + + int rc = new_set_type (pkbuf, pos, HICN_PACKET_TYPE_INTEREST); if (rc) return rc; - assert (is_interest (h->newhdr.flags)); - h->newhdr.prefix = name->prefix; - h->newhdr.suffix = htonl (name->suffix); + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + + new->prefix = name->prefix; + new->suffix = htonl (name->suffix); return HICN_LIB_ERROR_NONE; } int -new_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +new_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - assert (is_interest (h->newhdr.flags)); - *suffix = ntohl (h->newhdr.suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + + *suffix = ntohl (new->suffix); return HICN_LIB_ERROR_NONE; } int -new_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h, +new_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - assert (is_interest (h->newhdr.flags)); - h->newhdr.suffix = htonl (*suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + + new->suffix = htonl (*suffix); return HICN_LIB_ERROR_NONE; } int -new_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) +new_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - assert (is_interest (h->newhdr.flags)); - return CHILD_OPS (init_packet_header, type, h); + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -new_get_data_locator (hicn_type_t type, const hicn_protocol_t *h, - ip_address_t *ip_address) +new_get_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_ip_address_t *ip_address) { - assert (!is_interest (h->newhdr.flags)); + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); + return HICN_LIB_ERROR_NONE; } int -new_set_data_locator (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *ip_address) +new_set_data_locator (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *ip_address) { - assert (!is_interest (h->newhdr.flags)); + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + return HICN_LIB_ERROR_NONE; } int -new_get_data_name (hicn_type_t type, const hicn_protocol_t *h, +new_get_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_t *name) { - assert (!is_interest (h->newhdr.flags)); - name->prefix = h->newhdr.prefix; - name->suffix = ntohl (h->newhdr.suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + name->prefix = new->prefix; + name->suffix = ntohl (new->suffix); return HICN_LIB_ERROR_NONE; } int -new_set_data_name (hicn_type_t type, hicn_protocol_t *h, +new_set_data_name (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_t *name) { - new_mark_packet_as_data (type, h); - assert (!is_interest (h->newhdr.flags)); - h->newhdr.prefix = name->prefix; - h->newhdr.suffix = htonl (name->suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + int rc = new_set_type (pkbuf, pos, HICN_PACKET_TYPE_DATA); + if (rc) + return rc; + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + new->prefix = name->prefix; + new->suffix = htonl (name->suffix); return HICN_LIB_ERROR_NONE; } int -new_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +new_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - assert (!is_interest (h->newhdr.flags)); - *suffix = ntohl (h->newhdr.suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + *suffix = ntohl (new->suffix); return HICN_LIB_ERROR_NONE; } int -new_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, +new_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - assert (!is_interest (h->newhdr.flags)); - h->newhdr.suffix = htonl (*suffix); + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + new->suffix = htonl (*suffix); return HICN_LIB_ERROR_NONE; } int -new_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h, - u32 *pathlabel) +new_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t *path_label) { - assert (!is_interest (h->newhdr.flags)); - *pathlabel = h->newhdr.path_label; + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + *path_label = ntohl (new->path_label); return HICN_LIB_ERROR_NONE; } int -new_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const u32 pathlabel) +new_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t path_label) { - assert (!is_interest (h->newhdr.flags)); - h->newhdr.path_label = pathlabel; + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + new->path_label = htonl (path_label); return HICN_LIB_ERROR_NONE; } int -new_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const hicn_faceid_t face_id) +new_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_faceid_t face_id) { - hicn_pathlabel_t new_pl; - update_pathlabel (h->newhdr.path_label, face_id, &new_pl); - h->newhdr.path_label = new_pl; + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_path_label_t new_pl; + update_path_label (new->path_label, face_id, &new_pl); + new->path_label = new_pl; return HICN_LIB_ERROR_NONE; } int -new_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +new_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - return CHILD_OPS (reset_data_for_hash, type, h); + return CALL_CHILD (reset_data_for_hash, pkbuf, pos); } int -new_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, +new_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_lifetime_t *lifetime) { - *lifetime = ntohl (h->newhdr.lifetime); + _new_header_t *new = pkbuf_get_new (pkbuf); + + *lifetime = ntohl (new->lifetime); return HICN_LIB_ERROR_NONE; } int -new_set_lifetime (hicn_type_t type, hicn_protocol_t *h, +new_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_lifetime_t lifetime) { - h->newhdr.lifetime = htonl (lifetime); - return HICN_LIB_ERROR_NONE; -} + _new_header_t *new = pkbuf_get_new (pkbuf); -int -new_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) -{ + new->lifetime = htonl (lifetime); return HICN_LIB_ERROR_NONE; } int -new_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +new_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { return HICN_LIB_ERROR_NONE; } int -new_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +new_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first) { - assert (is_interest (h->newhdr.flags)); return HICN_LIB_ERROR_NONE; } int -new_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +new_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - assert (!is_interest (h->newhdr.flags)); return HICN_LIB_ERROR_NONE; } int -new_get_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +new_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { - *header_length = NEW_HDRLEN + ntohs (h->newhdr.payload_length); - return HICN_LIB_ERROR_NONE; -} + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); -int -new_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) -{ - *header_length = NEW_HDRLEN; - return HICN_LIB_ERROR_NONE; -} + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_INTEREST); -int -new_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) -{ - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *header_length = NEW_HDRLEN + child_header_length; return HICN_LIB_ERROR_NONE; } int -new_get_payload_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *payload_length) +new_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *payload_length = ntohs (h->newhdr.payload_length) - child_header_length; + _new_header_t *new = pkbuf_get_new (pkbuf); + _unused (new); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + return HICN_LIB_ERROR_NONE; } int -new_set_payload_length (hicn_type_t type, hicn_protocol_t *h, - size_t payload_length) +new_set_payload_len (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t payload_len) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - h->newhdr.payload_length = - htons ((u_short) (payload_length + child_header_length)); + _new_header_t *new = pkbuf_get_new (pkbuf); + + /* + * The value we have to store in the header is the sum of headers following + * the current header + the new payload size + */ + + size_t child_header_len = + (pkbuf->payload - pkbuf->newhdr) - sizeof (_new_header_t); + new->payload_len = htons ((u16) child_header_len + payload_len); return HICN_LIB_ERROR_NONE; } int -new_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, +new_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *signature_size) { - return CHILD_OPS (get_signature_size, type, h, signature_size); + return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size); } int -new_set_signature_size (hicn_type_t type, hicn_protocol_t *h, +new_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t signature_size) { - return CHILD_OPS (set_signature_size, type, h, signature_size); + return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size); } int -new_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, +new_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t padding) { - return CHILD_OPS (set_signature_padding, type, h, padding); + return CALL_CHILD (set_signature_padding, pkbuf, pos, padding); } int -new_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, +new_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *padding) { - return CHILD_OPS (get_signature_padding, type, h, padding); + return CALL_CHILD (get_signature_padding, pkbuf, pos, padding); } int -new_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, +new_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t signature_timestamp) { - return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp); } int -new_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, +new_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t *signature_timestamp) { - return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp); } int -new_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, +new_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t validation_algorithm) { - return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (set_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -new_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, +new_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *validation_algorithm) { - return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (get_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -new_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +new_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id, + size_t key_len) { - return CHILD_OPS (set_key_id, type, h, key_id); + return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len); } int -new_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size) +new_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **key_id, uint8_t *key_id_size) { - return CHILD_OPS (get_key_id, type, h, key_id, key_id_size); + return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size); } int -new_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature) +new_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **signature) { - return CHILD_OPS (get_signature, type, h, signature); + return CALL_CHILD (get_signature, pkbuf, pos, signature); } int -new_get_payload_type (hicn_type_t type, const hicn_protocol_t *h, +new_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag) +{ + _new_header_t *new = pkbuf_get_new (pkbuf); + + return new->flags &HICN_NEW_FLAG_SIG; +} + +int +new_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_payload_type_t *payload_type) { - *payload_type = ((h->newhdr.flags & HICN_NEW_FLAG_MAN) == HICN_NEW_FLAG_MAN); + _new_header_t *new = pkbuf_get_new (pkbuf); + + *payload_type = ((new->flags &HICN_NEW_FLAG_MAN) == HICN_NEW_FLAG_MAN); return HICN_LIB_ERROR_NONE; } int -new_set_payload_type (hicn_type_t type, hicn_protocol_t *h, +new_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_payload_type_t payload_type) { + _new_header_t *new = pkbuf_get_new (pkbuf); + if (payload_type != HPT_DATA && payload_type != HPT_MANIFEST) return HICN_LIB_ERROR_INVALID_PARAMETER; if (payload_type) - h->newhdr.flags |= HICN_NEW_FLAG_MAN; + new->flags |= HICN_NEW_FLAG_MAN; else - h->newhdr.flags &= ~HICN_NEW_FLAG_MAN; + new->flags &= ~HICN_NEW_FLAG_MAN; return HICN_LIB_ERROR_NONE; } int -new_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last) +new_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last) { - assert (!is_interest (h->newhdr.flags)); - *is_last = h->newhdr.flags & HICN_NEW_FLAG_LST; + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + *is_last = new->flags &HICN_NEW_FLAG_LST; return HICN_LIB_ERROR_NONE; } int -new_set_last_data (hicn_type_t type, hicn_protocol_t *h) +new_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos) { - assert (!is_interest (h->newhdr.flags)); - h->newhdr.flags |= HICN_NEW_FLAG_LST; + _new_header_t *new = pkbuf_get_new (pkbuf); + + hicn_packet_type_t type; + _ASSERT (new_get_type (pkbuf, pos, &type) == 0); + _ASSERT (type == HICN_PACKET_TYPE_DATA); + + new->flags |= HICN_NEW_FLAG_LST; return HICN_LIB_ERROR_NONE; } -DECLARE_HICN_OPS (new); +DECLARE_HICN_OPS (new, NEW_HDRLEN); #pragma GCC diagnostic pop diff --git a/lib/src/protocol/new.h b/lib/src/protocol/new.h new file mode 100644 index 000000000..7679910f4 --- /dev/null +++ b/lib/src/protocol/new.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file protocol/ah.h + * @brief AH packet header + */ +#ifndef HICN_PROTOCOL_NEW_H +#define HICN_PROTOCOL_NEW_H + +#include <hicn/common.h> +#include <hicn/name.h> + +/* + * The length of the new header struct must be 28 bytes. + */ +#define EXPECTED_NEW_HDRLEN 32 + +typedef struct +{ + u8 version_reserved; + u8 flags; + + /* Size of the payload direcly after the new header */ + u16 payload_len; + + u32 lifetime; + + /* Name prefix and suffix */ + hicn_ip_address_t prefix; + u32 suffix; + + /* We reserve 32 bits for the path label */ + u32 path_label; +} _new_header_t; + +#define NEW_HDRLEN sizeof (_new_header_t) +static_assert (EXPECTED_NEW_HDRLEN == NEW_HDRLEN, + "Size of new_header Struct does not match its expected size."); + +/* TCP flags bit 0 first. */ +#define foreach_hicn_new_flag \ + _ (SIG) /**< Signature header after. */ \ + _ (MAN) /**< Payload type is manifest. */ \ + _ (INT) /**< Packet is interest. */ \ + _ (LST) /**< Last data. */ + +enum +{ +#define _(f) HICN_NEW_FLAG_BIT_##f, + foreach_hicn_new_flag +#undef _ + HICN_NEW_N_FLAG_BITS, +}; + +enum +{ +#define _(f) HICN_NEW_FLAG_##f = 1 << HICN_NEW_FLAG_BIT_##f, + foreach_hicn_new_flag +#undef _ +}; + +static inline int +_get_new_header_version (const _new_header_t *new_hdr) +{ + return ((new_hdr->version_reserved >> 4) & 0x0F); +} + +static inline void +_set_new_header_version (_new_header_t *new_hdr) +{ + new_hdr->version_reserved = (0x9 << 4) & 0xF0; +} + +#endif /* HICN_PROTOCOL_NEW_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/tcp.c b/lib/src/protocol/tcp.c index 82fc461ea..822bd3e0c 100644 --- a/lib/src/protocol/tcp.c +++ b/lib/src/protocol/tcp.c @@ -14,9 +14,12 @@ */ #include <string.h> -#include <hicn/protocol/tcp.h> + +#include <hicn/base.h> #include <hicn/error.h> -#include <hicn/ops.h> + +#include "tcp.h" +#include "../ops.h" #define TCP_DEFAULT_SRC_PORT 0x8000 #define TCP_DEFAULT_DST_PORT 0x0080 @@ -32,6 +35,8 @@ #define TCP_DEFAULT_SYN 1 #define TCP_DEFAULT_FIN 0 +#define UINT16_T_MASK 0x0000ffff // 1111 1111 1111 1111 + DECLARE_get_interest_locator (tcp, UNEXPECTED); DECLARE_set_interest_locator (tcp, UNEXPECTED); DECLARE_get_interest_name (tcp, UNEXPECTED); @@ -40,21 +45,26 @@ DECLARE_get_data_locator (tcp, UNEXPECTED); DECLARE_set_data_locator (tcp, UNEXPECTED); DECLARE_get_data_name (tcp, UNEXPECTED); DECLARE_set_data_name (tcp, UNEXPECTED); -DECLARE_get_length (tcp, UNEXPECTED); -DECLARE_get_payload_length (tcp, UNEXPECTED); -DECLARE_set_payload_length (tcp, UNEXPECTED); +DECLARE_set_payload_len (tcp, UNEXPECTED); +DECLARE_get_ttl (tcp, UNEXPECTED); +DECLARE_set_ttl (tcp, UNEXPECTED); + +int tcp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first); static inline void -reset_for_hash (hicn_protocol_t *h) +reset_for_hash (hicn_packet_buffer_t *pkbuf) { - h->tcp.sport = 0; - h->tcp.dport = 0; - h->tcp.seq_ack = 0; - h->tcp.data_offset_and_reserved = 0; - h->tcp.flags = 0; - h->tcp.window = 0; - h->tcp.csum = 0; - h->tcp.urg_ptr = 0; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + tcp->sport = 0; + tcp->dport = 0; + tcp->seq_ack = 0; + tcp->data_offset_and_reserved = 0; + tcp->flags = 0; + tcp->window = 0; + tcp->csum = 0; + tcp->urg_ptr = 0; } static inline int @@ -80,9 +90,17 @@ check_tcp_checksum (u16 csum) } int -tcp_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +tcp_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - h->tcp = (_tcp_header_t){ + pkbuf->tcp = pkbuf->len; + if (TCP_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += TCP_HDRLEN; + + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + hicn_packet_format_t format = hicn_packet_get_format (pkbuf); + + *tcp = (_tcp_header_t){ .sport = htons (TCP_DEFAULT_SRC_PORT), .dport = htons (TCP_DEFAULT_DST_PORT), .seq = 0, @@ -97,142 +115,169 @@ tcp_init_packet_header (hicn_type_t type, hicn_protocol_t *h) .urg_ptr = 65000, }; - uint8_t ah_flag = type.l2 == IPPROTO_AH ? AH_FLAG : 0; + uint8_t ah_flag = ((format.as_u8[pos + 1] == IPPROTO_AH) ? AH_FLAG : 0); - h->tcp.flags |= ah_flag; + tcp->flags |= ah_flag; - return CHILD_OPS (init_packet_header, type, h); + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -tcp_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest) +tcp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type) { - *is_interest = (h->tcp.flags & HICN_TCP_FLAG_ECE) == 0; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + /* Data packets have the ECE bit set */ + if (tcp->flags & HICN_TCP_FLAG_ECE) + *type = HICN_PACKET_TYPE_DATA; + else + *type = HICN_PACKET_TYPE_INTEREST; return HICN_LIB_ERROR_NONE; } int -tcp_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h) +tcp_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type) { - h->tcp.flags &= ~HICN_TCP_FLAG_ECE; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + switch (type) + { + case HICN_PACKET_TYPE_INTEREST: + tcp->flags &= ~HICN_TCP_FLAG_ECE; + break; + case HICN_PACKET_TYPE_DATA: + tcp->flags |= HICN_TCP_FLAG_ECE; + break; + default: + return HICN_LIB_ERROR_INVALID_PARAMETER; + } return HICN_LIB_ERROR_NONE; } int -tcp_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - *suffix = ntohl (h->tcp.name_suffix); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *suffix = ntohl (tcp->name_suffix); return HICN_LIB_ERROR_NONE; } int -tcp_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h, +tcp_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - int rc = tcp_mark_packet_as_interest (type, h); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + int rc = tcp_set_type (pkbuf, pos, HICN_PACKET_TYPE_INTEREST); if (rc) return rc; - h->tcp.name_suffix = htonl (*suffix); + tcp->name_suffix = htonl (*suffix); return HICN_LIB_ERROR_NONE; } int -tcp_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) +tcp_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - h->tcp.flags |= HICN_TCP_FLAG_ECE; - return HICN_LIB_ERROR_NONE; + reset_for_hash (pkbuf); + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -tcp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) -{ - reset_for_hash (h); - return CHILD_OPS (reset_interest_for_hash, type, h); -} - -int -tcp_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - *suffix = ntohl (h->tcp.name_suffix); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *suffix = ntohl (tcp->name_suffix); return HICN_LIB_ERROR_NONE; } int -tcp_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, +tcp_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - int rc = tcp_mark_packet_as_data (type, h); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + int rc = tcp_set_type (pkbuf, pos, HICN_PACKET_TYPE_DATA); if (rc) return rc; - h->tcp.name_suffix = htonl (*suffix); + tcp->name_suffix = htonl (*suffix); return HICN_LIB_ERROR_NONE; } int -tcp_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h, - u32 *pathlabel) +tcp_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t *path_label) { - *pathlabel = h->tcp.seq_ack; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *path_label = + (hicn_path_label_t) (tcp->seq_ack >> (32 - HICN_PATH_LABEL_SIZE_BITS)); return HICN_LIB_ERROR_NONE; } int -tcp_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const u32 pathlabel) +tcp_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t path_label) { - h->tcp.seq_ack = pathlabel; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + hicn_path_label_t old_path_label; + tcp_get_data_path_label (pkbuf, pos, &old_path_label); + + tcp->seq_ack = (path_label << (32 - HICN_PATH_LABEL_SIZE_BITS)); + + tcp_update_checksums_incremental ( + pkbuf, pos, (uint16_t *) &old_path_label, (uint16_t *) &path_label, + sizeof (hicn_path_label_t) / sizeof (uint16_t), true); + return HICN_LIB_ERROR_NONE; } int -tcp_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const hicn_faceid_t face_id) +tcp_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_faceid_t face_id) { - hicn_pathlabel_t pl = - (hicn_pathlabel_t) (h->tcp.seq_ack >> (32 - HICN_PATH_LABEL_SIZE)); + assert (sizeof (hicn_path_label_t) == 1); - hicn_pathlabel_t new_pl; + hicn_path_label_t old_path_label; + hicn_path_label_t new_path_label; - update_pathlabel (pl, face_id, &new_pl); - h->tcp.seq_ack = (new_pl << (32 - HICN_PATH_LABEL_SIZE)); + tcp_get_data_path_label (pkbuf, pos, &old_path_label); + update_path_label (old_path_label, face_id, &new_path_label); + tcp_set_data_path_label (pkbuf, pos, new_path_label); return HICN_LIB_ERROR_NONE; } int -tcp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +tcp_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - reset_for_hash (h); - return CHILD_OPS (reset_data_for_hash, type, h); + reset_for_hash (pkbuf); + return CALL_CHILD (reset_data_for_hash, pkbuf, pos); } int -tcp_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_lifetime_t *lifetime) { - *lifetime = ntohs (h->tcp.urg_ptr) - << (h->tcp.data_offset_and_reserved & 0xF); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *lifetime = ntohs (tcp->urg_ptr) << (tcp->data_offset_and_reserved & 0xF); return HICN_LIB_ERROR_NONE; } int -tcp_set_lifetime (hicn_type_t type, hicn_protocol_t *h, +tcp_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_lifetime_t lifetime) { + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); u8 multiplier = 0; u32 lifetime_scaled = lifetime; - if (PREDICT_FALSE (lifetime >= HICN_MAX_LIFETIME)) + if (HICN_EXPECT_FALSE (lifetime >= HICN_MAX_LIFETIME)) { - h->tcp.urg_ptr = htons (HICN_MAX_LIFETIME_SCALED); - h->tcp.data_offset_and_reserved = - (h->tcp.data_offset_and_reserved & ~0x0F) | - HICN_MAX_LIFETIME_MULTIPLIER; + tcp->urg_ptr = htons (HICN_MAX_LIFETIME_SCALED); + tcp->data_offset_and_reserved = + (tcp->data_offset_and_reserved & ~0x0F) | HICN_MAX_LIFETIME_MULTIPLIER; return HICN_LIB_ERROR_NONE; } @@ -243,70 +288,76 @@ tcp_set_lifetime (hicn_type_t type, hicn_protocol_t *h, lifetime_scaled = lifetime_scaled >> 1; } - h->tcp.urg_ptr = htons (lifetime_scaled); - h->tcp.data_offset_and_reserved = - (h->tcp.data_offset_and_reserved & ~0x0F) | multiplier; + tcp->urg_ptr = htons (lifetime_scaled); + tcp->data_offset_and_reserved = + (tcp->data_offset_and_reserved & ~0x0F) | multiplier; return HICN_LIB_ERROR_NONE; } int -tcp_get_source_port (hicn_type_t type, const hicn_protocol_t *h, - u16 *source_port) +tcp_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - *source_port = ntohs (h->tcp.sport); - return HICN_LIB_ERROR_NONE; -} + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + /* TODO bound checks for payload_len based on pkbuf size */ + assert (payload_len != ~0); -int -tcp_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port) -{ - *dest_port = ntohs (h->tcp.dport); - return HICN_LIB_ERROR_NONE; -} + tcp->csum = 0; -int -tcp_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port) -{ - h->tcp.sport = htons (source_port); - return HICN_LIB_ERROR_NONE; -} + if (HICN_EXPECT_TRUE (partial_csum != 0)) + { + partial_csum = ~partial_csum; + } -int -tcp_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port) -{ - h->tcp.dport = htons (dest_port); - return HICN_LIB_ERROR_NONE; + tcp->csum = + csum (pkbuf_get_header (pkbuf), TCP_HDRLEN + payload_len, partial_csum); + + return CALL_CHILD (update_checksums, pkbuf, pos, 0, payload_len); } int -tcp_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +tcp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first) { - h->tcp.csum = 0; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + if (skip_first) + return HICN_LIB_ERROR_INVALID_PARAMETER; - if (PREDICT_TRUE (partial_csum != 0)) + for (uint8_t i = 0; i < size; i++) { - partial_csum = ~partial_csum; + uint16_t old_csum = ~tcp->csum; + uint16_t not_old_val = ~(*old_val); + uint32_t sum = (uint32_t) old_csum + not_old_val + *new_val; + + while (sum >> 16) + { + sum = (sum >> 16) + (sum & UINT16_T_MASK); + } + + tcp->csum = ~sum; + ++old_val; + ++new_val; } - h->tcp.csum = csum (h, TCP_HDRLEN + payload_length, partial_csum); - - return CHILD_OPS (update_checksums, type, h, 0, payload_length); + return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val, + new_val, size, false); } int -tcp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +tcp_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - if (PREDICT_TRUE (partial_csum != 0)) + if (HICN_EXPECT_TRUE (partial_csum != 0)) { partial_csum = ~partial_csum; } - if (csum (h, TCP_HDRLEN + payload_length, partial_csum) != 0) + if (csum (pkbuf_get_header (pkbuf), TCP_HDRLEN + payload_len, + partial_csum) != 0) return HICN_LIB_ERROR_CORRUPTED_PACKET; - return CHILD_OPS (verify_checksums, type, h, 0, payload_length); + return CALL_CHILD (verify_checksums, pkbuf, pos, 0, payload_len); } #define TCP_OFFSET_MASK 13 @@ -331,10 +382,14 @@ tcp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, #define TCP_DEFAULT_FIN 0 int -tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +tcp_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { - u16 *tcp_checksum = &(h->tcp.csum); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + _ipv6_header_t *ip6 = pkbuf_get_ipv6 (pkbuf); + + u16 *tcp_checksum = &(tcp->csum); int ret = check_tcp_checksum (*tcp_checksum); if (ret) @@ -347,14 +402,14 @@ tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, * whole struct by interpreting it as IPv6 in all cases * * v4 code would be: - * csum = ip_csum_sub_even (*tcp_checksum, h->ipv4.saddr.as_u32); - * csum = ip_csum_add_even (csum, h->ipv4.saddr.as_u32); + * csum = ip_csum_sub_even (*tcp_checksum, h->tcp.saddr.as_u32); + * csum = ip_csum_add_even (csum, h->tcp.saddr.as_u32); */ - ip_csum_t csum = - ip_csum_sub_even (*tcp_checksum, (ip_csum_t) (h->ipv6.saddr.as_u64[0])); - csum = ip_csum_sub_even (csum, (ip_csum_t) (h->ipv6.saddr.as_u64[1])); - csum = ip_csum_add_even (csum, (ip_csum_t) (h->ipv6.saddr.as_u64[0])); - csum = ip_csum_add_even (csum, (ip_csum_t) (h->ipv6.saddr.as_u64[1])); + hicn_ip_csum_t csum = + ip_csum_sub_even (*tcp_checksum, (hicn_ip_csum_t) (ip6->saddr.as_u64[0])); + csum = ip_csum_sub_even (csum, (hicn_ip_csum_t) (ip6->saddr.as_u64[1])); + csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (ip6->saddr.as_u64[0])); + csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (ip6->saddr.as_u64[1])); *tcp_checksum = ip_csum_fold (csum); @@ -362,21 +417,22 @@ tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, } int -tcp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +tcp_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { - - u16 *tcp_checksum = &(h->tcp.csum); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + u16 *tcp_checksum = &(tcp->csum); int ret = check_tcp_checksum (*tcp_checksum); /* * update path label */ - u16 old_pl = h->tcp.seq_ack; + u16 old_pl = tcp->seq_ack; if (reset_pl) - h->tcp.seq_ack = 0; - tcp_update_data_pathlabel (type, h, face_id); + tcp->seq_ack = 0; + tcp_update_data_path_label (pkbuf, pos, face_id); if (ret) { @@ -388,18 +444,18 @@ tcp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, * whole struct by interpreting it as IPv6 in all cases * * v4 code would be: - * csum = ip_csum_sub_even (*tcp_checksum, h->ipv4.saddr.as_u32); - * csum = ip_csum_add_even (csum, h->ipv4.saddr.as_u32); + * csum = ip_csum_sub_even (*tcp_checksum, h->tcp.saddr.as_u32); + * csum = ip_csum_add_even (csum, h->tcp.saddr.as_u32); */ - ip_csum_t csum = - ip_csum_sub_even (*tcp_checksum, (ip_csum_t) (addr_old->v6.as_u64[0])); - csum = - ip_csum_sub_even (*tcp_checksum, (ip_csum_t) (addr_old->v6.as_u64[1])); - csum = ip_csum_add_even (csum, (ip_csum_t) (addr_new->v6.as_u64[0])); - csum = ip_csum_add_even (csum, (ip_csum_t) (addr_new->v6.as_u64[1])); + hicn_ip_csum_t csum = ip_csum_sub_even ( + *tcp_checksum, (hicn_ip_csum_t) (addr_old->v6.as_u64[0])); + csum = ip_csum_sub_even (*tcp_checksum, + (hicn_ip_csum_t) (addr_old->v6.as_u64[1])); + csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (addr_new->v6.as_u64[0])); + csum = ip_csum_add_even (csum, (hicn_ip_csum_t) (addr_new->v6.as_u64[1])); csum = ip_csum_sub_even (csum, old_pl); - csum = ip_csum_add_even (csum, h->tcp.seq_ack); + csum = ip_csum_add_even (csum, tcp->seq_ack); *tcp_checksum = ip_csum_fold (csum); @@ -407,139 +463,166 @@ tcp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, } int -tcp_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) -{ - *header_length = TCP_HDRLEN; - return HICN_LIB_ERROR_NONE; -} - -int -tcp_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) -{ - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - - *header_length = TCP_HDRLEN + child_header_length; - return HICN_LIB_ERROR_NONE; -} - -int -tcp_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *signature_size) { - return CHILD_OPS (get_signature_size, type, h, signature_size); + return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size); } int -tcp_set_signature_size (hicn_type_t type, hicn_protocol_t *h, +tcp_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t signature_size) { - return CHILD_OPS (set_signature_size, type, h, signature_size); + return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size); } int -tcp_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, +tcp_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t padding) { - return CHILD_OPS (set_signature_padding, type, h, padding); + return CALL_CHILD (set_signature_padding, pkbuf, pos, padding); } int -tcp_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, size_t *padding) { - return CHILD_OPS (get_signature_padding, type, h, padding); + return CALL_CHILD (get_signature_padding, pkbuf, pos, padding); } int -tcp_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, +tcp_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t signature_timestamp) { - return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp); } int -tcp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, uint64_t *signature_timestamp) { - return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp); } int -tcp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, +tcp_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t validation_algorithm) { - return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (set_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -tcp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, +tcp_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *validation_algorithm) { - return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (get_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -tcp_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +tcp_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id, + size_t key_len) { - return CHILD_OPS (set_key_id, type, h, key_id); + return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len); } int -tcp_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size) +tcp_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **key_id, uint8_t *key_id_size) { - return CHILD_OPS (get_key_id, type, h, key_id, key_id_size); + return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size); } int -tcp_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature) +tcp_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **signature) { - return CHILD_OPS (get_signature, type, h, signature); + return CALL_CHILD (get_signature, pkbuf, pos, signature); } int -tcp_get_payload_type (hicn_type_t type, const hicn_protocol_t *h, +tcp_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag) +{ + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *flag = tcp->flags & AH_FLAG; + return HICN_LIB_ERROR_NONE; +} + +int +tcp_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_payload_type_t *payload_type) { - *payload_type = ((h->tcp.flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG); + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *payload_type = ((tcp->flags & HICN_TCP_FLAG_URG) == HICN_TCP_FLAG_URG); return HICN_LIB_ERROR_NONE; } int -tcp_set_payload_type (hicn_type_t type, hicn_protocol_t *h, +tcp_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_payload_type_t payload_type) { + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); if (payload_type != HPT_DATA && payload_type != HPT_MANIFEST) return HICN_LIB_ERROR_INVALID_PARAMETER; if (payload_type) - h->tcp.flags |= HICN_TCP_FLAG_URG; + tcp->flags |= HICN_TCP_FLAG_URG; else - h->tcp.flags &= ~HICN_TCP_FLAG_URG; + tcp->flags &= ~HICN_TCP_FLAG_URG; + + return HICN_LIB_ERROR_NONE; +} + +int +tcp_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last) +{ + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *is_last = (tcp->flags & HICN_TCP_FLAG_RST) == HICN_TCP_FLAG_RST; + return HICN_LIB_ERROR_NONE; +} +int +tcp_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos) +{ + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + tcp->flags |= HICN_TCP_FLAG_RST; + return HICN_LIB_ERROR_NONE; +} + +int +tcp_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) +{ + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *port = ntohs (tcp->sport); + return HICN_LIB_ERROR_NONE; +} + +int +tcp_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) +{ + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + tcp->sport = htons (port); return HICN_LIB_ERROR_NONE; } int -tcp_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last) +tcp_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - *is_last = (h->tcp.flags & HICN_TCP_FLAG_RST) == HICN_TCP_FLAG_RST; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + *port = ntohs (tcp->dport); return HICN_LIB_ERROR_NONE; } int -tcp_set_last_data (hicn_type_t type, hicn_protocol_t *h) +tcp_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - h->tcp.flags |= HICN_TCP_FLAG_RST; + _tcp_header_t *tcp = pkbuf_get_tcp (pkbuf); + tcp->dport = htons (port); return HICN_LIB_ERROR_NONE; } -DECLARE_HICN_OPS (tcp); +DECLARE_HICN_OPS (tcp, TCP_HDRLEN); /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/protocol/tcp.h b/lib/src/protocol/tcp.h new file mode 100644 index 000000000..e563372d0 --- /dev/null +++ b/lib/src/protocol/tcp.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HICN_PROTOCOL_TCP_H +#define HICN_PROTOCOL_TCP_H + +#include <hicn/base.h> +#include <hicn/common.h> +#include <hicn/name.h> + +/* + * The length of the TCP header struct must be 20 bytes. + */ +#define EXPECTED_TCP_HDRLEN 20 + +/* + * NOTE: bitfields are problematic for portability reasons. There are provided + * here for reference and documentation purposes, we might just provide a macro + * to disable and use it instead of __BYTE_ORDER__. + */ +typedef struct +{ + u16 sport; + u16 dport; + union + { + u32 seq; + hicn_name_suffix_t name_suffix; + }; + union + { + u32 seq_ack; + struct + { + hicn_path_label_t pathlabel; + u8 pad[3]; + }; + }; + + union + { + struct + { + u8 data_offset_and_reserved; + u8 flags; + }; +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + struct + { + u16 reserved : 4; + u16 doff : 4; + u16 fin : 1; + u16 syn : 1; + u16 rst : 1; + u16 psh : 1; + u16 ack : 1; + u16 urg : 1; + u16 ece : 1; + u16 cwr : 1; + }; + struct + { /* __ denotes unchanged bitfields */ + u16 timescale : 4; + u16 __doff : 4; + u16 __fin : 1; + u16 __syn : 1; + u16 __rst : 1; + u16 sig : 1; + u16 __ack : 1; + u16 man : 1; + u16 id : 1; + u16 __cwr : 1; + }; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + struct + { + u16 doff : 4; + u16 reserved : 4; + u16 cwr : 1; + u16 ece : 1; + u16 urg : 1; + u16 ack : 1; + u16 psh : 1; + u16 rst : 1; + u16 syn : 1; + u16 fin : 1; + }; + struct + { + u16 __doff : 4; + u16 timescale : 4; + u16 __cwr : 1; + u16 id : 1 u16 man : 1; + u16 __ack : 1; + u16 sig : 1; + u16 __rst : 1; + u16 __syn : 1; + u16 __fin : 1; + }; +#endif + }; + union + { + u16 window; + u16 ldr; + }; + u16 csum; + union + { + u16 urg_ptr; + u16 lifetime; + }; +} _tcp_header_t; + +#define TCP_HDRLEN sizeof (_tcp_header_t) +static_assert (EXPECTED_TCP_HDRLEN == TCP_HDRLEN, + "Size of TCP struct does not match its expected size."); + +/* TCP flags bit 0 first. */ +#define foreach_tcp_flag \ + _ (FIN) /**< No more data from sender. */ \ + _ (SYN) /**< Synchronize sequence numbers. */ \ + _ (RST) /**< Reset the connection. */ \ + _ (PSH) /**< Push function. */ \ + _ (ACK) /**< Ack field significant. */ \ + _ (URG) /**< Urgent pointer field significant. */ \ + _ (ECE) /**< ECN-echo. Receiver got CE packet */ \ + _ (CWR) /**< Sender reduced congestion window */ + +enum +{ +#define _(f) HICN_TCP_FLAG_BIT_##f, + foreach_tcp_flag +#undef _ + HICN_TCP_N_FLAG_BITS, +}; + +enum +{ +#define _(f) HICN_TCP_FLAG_##f = 1 << HICN_TCP_FLAG_BIT_##f, + foreach_tcp_flag +#undef _ +}; + +#endif /* HICN_PROTOCOL_TCP_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/protocol/udp.c b/lib/src/protocol/udp.c index 7a14b09c2..ff2355b0c 100644 --- a/lib/src/protocol/udp.c +++ b/lib/src/protocol/udp.c @@ -17,9 +17,9 @@ #include <string.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/ops.h> -#include <hicn/protocol/udp.h> +#include "udp.h" +#include "../ops.h" DECLARE_get_interest_locator (udp, UNEXPECTED); DECLARE_set_interest_locator (udp, UNEXPECTED); @@ -29,308 +29,313 @@ DECLARE_get_data_locator (udp, UNEXPECTED); DECLARE_set_data_locator (udp, UNEXPECTED); DECLARE_get_data_name (udp, UNEXPECTED); DECLARE_set_data_name (udp, UNEXPECTED); -DECLARE_get_payload_length (udp, UNEXPECTED); -DECLARE_set_payload_length (udp, UNEXPECTED); +DECLARE_set_payload_len (udp, UNEXPECTED); +DECLARE_get_ttl (udp, UNEXPECTED); +DECLARE_set_ttl (udp, UNEXPECTED); int -udp_init_packet_header (hicn_type_t type, hicn_protocol_t *h) +udp_init_packet_header (hicn_packet_buffer_t *pkbuf, size_t pos) { - size_t total_header_length; - int rc = CHILD_OPS (get_header_length, type, h, &total_header_length); - if (rc < 0) - return rc; + pkbuf->udp = pkbuf->len; + if (UDP_HDRLEN > pkbuf->buffer_size - pkbuf->len) + return -1; + pkbuf->len += UDP_HDRLEN; - /* *INDENT-OFF* */ - h->udp = (_udp_header_t){ .src_port = 0, - .dst_port = 0, - .length = htons ((u16) total_header_length), - .checksum = 0 }; - /* *INDENT-ON* */ - return CHILD_OPS (init_packet_header, type, h); + _udp_header_t *udp = pkbuf_get_udp (pkbuf); + + size_t len = hicn_packet_get_len (pkbuf) - + ((u8 *) udp - pkbuf_get_header (pkbuf)) - + sizeof (_udp_header_t); + + // clang-format off + *udp = (_udp_header_t){ + .src_port = 0, + .dst_port = 0, + .len = htons ((u16) len), + .checksum = 0 + }; + // clang-format on + return CALL_CHILD (init_packet_header, pkbuf, pos); } int -udp_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +udp_get_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - return CHILD_OPS (get_interest_name_suffix, type, h, suffix); + return CALL_CHILD (get_interest_name_suffix, pkbuf, pos, suffix); } int -udp_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t *h, +udp_set_interest_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - return CHILD_OPS (set_interest_name_suffix, type, h, suffix); -} - -int -udp_is_interest (hicn_type_t type, const hicn_protocol_t *h, int *is_interest) -{ - return CHILD_OPS (is_interest, type, h, is_interest); + return CALL_CHILD (set_interest_name_suffix, pkbuf, pos, suffix); } int -udp_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t *h) +udp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, + hicn_packet_type_t *type) { - return CHILD_OPS (mark_packet_as_interest, type, h); + return CALL_CHILD (get_type, pkbuf, pos, type); } int -udp_mark_packet_as_data (hicn_type_t type, hicn_protocol_t *h) +udp_set_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_packet_type_t type) { - return CHILD_OPS (mark_packet_as_data, type, h); + return CALL_CHILD (set_type, pkbuf, pos, type); } int -udp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t *h) +udp_reset_interest_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - return CHILD_OPS (reset_interest_for_hash, type, h); + return CALL_CHILD (reset_interest_for_hash, pkbuf, pos); } int -udp_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t *h, +udp_get_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_name_suffix_t *suffix) { - return CHILD_OPS (get_data_name_suffix, type, h, suffix); + return CALL_CHILD (get_data_name_suffix, pkbuf, pos, suffix); } int -udp_set_data_name_suffix (hicn_type_t type, hicn_protocol_t *h, +udp_set_data_name_suffix (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_name_suffix_t *suffix) { - return CHILD_OPS (set_data_name_suffix, type, h, suffix); + return CALL_CHILD (set_data_name_suffix, pkbuf, pos, suffix); } int -udp_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t *h, - u32 *pathlabel) +udp_get_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t *path_label) { - return CHILD_OPS (get_data_pathlabel, type, h, pathlabel); + return CALL_CHILD (get_data_path_label, pkbuf, pos, path_label); } int -udp_set_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const u32 pathlabel) +udp_set_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_path_label_t path_label) { - return CHILD_OPS (set_data_pathlabel, type, h, pathlabel); + return CALL_CHILD (set_data_path_label, pkbuf, pos, path_label); } int -udp_update_data_pathlabel (hicn_type_t type, hicn_protocol_t *h, - const hicn_faceid_t face_id) +udp_update_data_path_label (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_faceid_t face_id) { - return CHILD_OPS (update_data_pathlabel, type, h, face_id); + return CALL_CHILD (update_data_path_label, pkbuf, pos, face_id); } int -udp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t *h) +udp_reset_data_for_hash (hicn_packet_buffer_t *pkbuf, size_t pos) { - return CHILD_OPS (reset_data_for_hash, type, h); + return CALL_CHILD (reset_data_for_hash, pkbuf, pos); } int -udp_get_lifetime (hicn_type_t type, const hicn_protocol_t *h, +udp_get_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, hicn_lifetime_t *lifetime) { - return CHILD_OPS (get_lifetime, type, h, lifetime); + return CALL_CHILD (get_lifetime, pkbuf, pos, lifetime); } int -udp_set_lifetime (hicn_type_t type, hicn_protocol_t *h, +udp_set_lifetime (const hicn_packet_buffer_t *pkbuf, size_t pos, const hicn_lifetime_t lifetime) { - return CHILD_OPS (set_lifetime, type, h, lifetime); + return CALL_CHILD (set_lifetime, pkbuf, pos, lifetime); } int -udp_get_source_port (hicn_type_t type, const hicn_protocol_t *h, - u16 *source_port) +udp_update_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - *source_port = ntohs (h->udp.src_port); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (update_checksums, pkbuf, pos, partial_csum, payload_len); } int -udp_get_dest_port (hicn_type_t type, const hicn_protocol_t *h, u16 *dest_port) +udp_update_checksums_incremental (const hicn_packet_buffer_t *pkbuf, + size_t pos, u16 *old_val, u16 *new_val, + u8 size, bool skip_first) { - *dest_port = ntohs (h->udp.dst_port); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (update_checksums_incremental, pkbuf, pos, old_val, + new_val, size, false); } int -udp_set_source_port (hicn_type_t type, hicn_protocol_t *h, u16 source_port) +udp_verify_checksums (const hicn_packet_buffer_t *pkbuf, size_t pos, + u16 partial_csum, size_t payload_len) { - h->udp.src_port = htons (source_port); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (verify_checksums, pkbuf, pos, partial_csum, payload_len); } int -udp_set_dest_port (hicn_type_t type, hicn_protocol_t *h, u16 dest_port) +udp_rewrite_interest (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old) { - h->udp.dst_port = htons (dest_port); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (rewrite_interest, pkbuf, pos, addr_new, addr_old); } int -udp_update_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +udp_rewrite_data (const hicn_packet_buffer_t *pkbuf, size_t pos, + const hicn_ip_address_t *addr_new, + hicn_ip_address_t *addr_old, const hicn_faceid_t face_id, + u8 reset_pl) { - return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length); + return CALL_CHILD (rewrite_data, pkbuf, pos, addr_new, addr_old, face_id, + reset_pl); } int -udp_verify_checksums (hicn_type_t type, hicn_protocol_t *h, u16 partial_csum, - size_t payload_length) +udp_get_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t *payload_type) { - return CHILD_OPS (verify_checksums, type, h, partial_csum, payload_length); + return CALL_CHILD (get_payload_type, pkbuf, pos, payload_type); } int -udp_rewrite_interest (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old) +udp_set_payload_type (const hicn_packet_buffer_t *pkbuf, size_t pos, + hicn_payload_type_t payload_type) { - return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old); + return CALL_CHILD (set_payload_type, pkbuf, pos, payload_type); } int -udp_rewrite_data (hicn_type_t type, hicn_protocol_t *h, - const ip_address_t *addr_new, ip_address_t *addr_old, - const hicn_faceid_t face_id, u8 reset_pl) +udp_get_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t *signature_size) { - return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id, - reset_pl); + return CALL_CHILD (get_signature_size, pkbuf, pos, signature_size); } int -udp_get_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +udp_set_signature_size (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t signature_size) { - *header_length = IPV6_HDRLEN + ntohs (h->ipv6.len); - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_signature_size, pkbuf, pos, signature_size); } int -udp_get_current_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +udp_has_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, bool *flag) { - *header_length = UDP_HDRLEN; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (has_signature, pkbuf, pos, flag); } int -udp_get_header_length (hicn_type_t type, const hicn_protocol_t *h, - size_t *header_length) +udp_set_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t padding) { - size_t child_header_length = 0; - int rc = CHILD_OPS (get_header_length, type, h, &child_header_length); - if (rc < 0) - return rc; - *header_length = UDP_HDRLEN + child_header_length; - return HICN_LIB_ERROR_NONE; + return CALL_CHILD (set_signature_padding, pkbuf, pos, padding); } int -udp_get_payload_type (hicn_type_t type, const hicn_protocol_t *h, - hicn_payload_type_t *payload_type) +udp_get_signature_padding (const hicn_packet_buffer_t *pkbuf, size_t pos, + size_t *padding) { - return CHILD_OPS (get_payload_type, type, h, payload_type); + return CALL_CHILD (get_signature_padding, pkbuf, pos, padding); } int -udp_set_payload_type (hicn_type_t type, hicn_protocol_t *h, - hicn_payload_type_t payload_type) +udp_set_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint64_t signature_timestamp) { - return CHILD_OPS (set_payload_type, type, h, payload_type); + return CALL_CHILD (set_signature_timestamp, pkbuf, pos, signature_timestamp); } int -udp_get_signature_size (hicn_type_t type, const hicn_protocol_t *h, - size_t *signature_size) +udp_get_signature_timestamp (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint64_t *signature_timestamp) { - return CHILD_OPS (get_signature_size, type, h, signature_size); + return CALL_CHILD (get_signature_timestamp, pkbuf, pos, signature_timestamp); } int -udp_set_signature_size (hicn_type_t type, hicn_protocol_t *h, - size_t signature_size) +udp_set_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t validation_algorithm) { - return CHILD_OPS (set_signature_size, type, h, signature_size); + return CALL_CHILD (set_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -udp_set_signature_padding (hicn_type_t type, hicn_protocol_t *h, - size_t padding) +udp_get_validation_algorithm (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t *validation_algorithm) { - return CHILD_OPS (set_signature_padding, type, h, padding); + return CALL_CHILD (get_validation_algorithm, pkbuf, pos, + validation_algorithm); } int -udp_get_signature_padding (hicn_type_t type, const hicn_protocol_t *h, - size_t *padding) +udp_set_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, uint8_t *key_id, + size_t key_len) { - return CHILD_OPS (get_signature_padding, type, h, padding); + return CALL_CHILD (set_key_id, pkbuf, pos, key_id, key_len); } int -udp_set_signature_timestamp (hicn_type_t type, hicn_protocol_t *h, - uint64_t signature_timestamp) +udp_get_key_id (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **key_id, uint8_t *key_id_size) { - return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_key_id, pkbuf, pos, key_id, key_id_size); } int -udp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t *h, - uint64_t *signature_timestamp) +udp_get_signature (const hicn_packet_buffer_t *pkbuf, size_t pos, + uint8_t **signature) { - return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp); + return CALL_CHILD (get_signature, pkbuf, pos, signature); } int -udp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t *h, - uint8_t validation_algorithm) +udp_is_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos, int *is_last) { - return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (is_last_data, pkbuf, pos, is_last); } int -udp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t *h, - uint8_t *validation_algorithm) +udp_set_last_data (const hicn_packet_buffer_t *pkbuf, size_t pos) { - return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm); + return CALL_CHILD (set_last_data, pkbuf, pos); } int -udp_set_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t *key_id) +udp_get_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - return CHILD_OPS (set_key_id, type, h, key_id); -} + _udp_header_t *udp = pkbuf_get_udp (pkbuf); -int -udp_get_key_id (hicn_type_t type, hicn_protocol_t *h, uint8_t **key_id, - uint8_t *key_id_size) -{ - return CHILD_OPS (get_key_id, type, h, key_id, key_id_size); + *port = udp->src_port; + return HICN_LIB_ERROR_NONE; } int -udp_get_signature (hicn_type_t type, hicn_protocol_t *h, uint8_t **signature) +udp_set_src_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - return CHILD_OPS (get_signature, type, h, signature); + _udp_header_t *udp = pkbuf_get_udp (pkbuf); + + udp->src_port = port; + return HICN_LIB_ERROR_NONE; } int -udp_is_last_data (hicn_type_t type, const hicn_protocol_t *h, int *is_last) +udp_get_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 *port) { - return CHILD_OPS (is_last_data, type, h, is_last); + _udp_header_t *udp = pkbuf_get_udp (pkbuf); + + *port = udp->dst_port; + return HICN_LIB_ERROR_NONE; } int -udp_set_last_data (hicn_type_t type, hicn_protocol_t *h) +udp_set_dst_port (const hicn_packet_buffer_t *pkbuf, size_t pos, u16 port) { - return CHILD_OPS (set_last_data, type, h); + _udp_header_t *udp = pkbuf_get_udp (pkbuf); + + udp->dst_port = port; + return HICN_LIB_ERROR_NONE; } -DECLARE_HICN_OPS (udp); +DECLARE_HICN_OPS (udp, UDP_HDRLEN); /* * fd.io coding-style-patch-verification: ON diff --git a/lib/src/protocol/udp.h b/lib/src/protocol/udp.h new file mode 100644 index 000000000..23f5317b3 --- /dev/null +++ b/lib/src/protocol/udp.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HICN_PROTOCOL_UDP_H +#define HICN_PROTOCOL_UDP_H + +/* + * The len of the UDP header struct must be 8 bytes. + */ +#define EXPECTED_UDP_HDRLEN 8 + +typedef struct +{ + u16 src_port; + u16 dst_port; + u16 len; + u16 checksum; +} _udp_header_t; + +#define UDP_HDRLEN sizeof (_udp_header_t) +static_assert (EXPECTED_UDP_HDRLEN == UDP_HDRLEN, + "Size of UDP struct does not match its expected size."); + +#endif /* HICN_PROTOCOL_UDP_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/lib/src/test/CMakeLists.txt b/lib/src/test/CMakeLists.txt index 3e3c025c7..17cf835d2 100644 --- a/lib/src/test/CMakeLists.txt +++ b/lib/src/test/CMakeLists.txt @@ -22,6 +22,12 @@ list(APPEND TESTS_SRC test_new_header.cc test_udp_header.cc test_validation.cc + test_bitmap.cc + test_interest_manifest.cc + test_khash.cc + test_pool.cc + test_ring.cc + test_vector.cc ) ############################################################## diff --git a/lib/src/test/test_bitmap.cc b/lib/src/test/test_bitmap.cc new file mode 100644 index 000000000..7fc8eef71 --- /dev/null +++ b/lib/src/test/test_bitmap.cc @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#define WITH_TESTS +#include <hicn/util/bitmap.h> +} + +#define DEFAULT_SIZE 10 + +class BitmapTest : public ::testing::Test +{ +protected: + BitmapTest () {} + + virtual ~BitmapTest () {} + + bitmap_t *bitmap; +}; + +/* + * TEST: bitmap allocation + */ +TEST_F (BitmapTest, BitmapAllocation) +{ + int rc; + + /* + * We take a value < 32 on purpose to avoid confusion on the choice of a 32 + * or 64 bit integer for storage + */ + size_t size_not_pow2 = DEFAULT_SIZE; + bitmap_init (bitmap, size_not_pow2, 0); + + /* + * Bitmap should have been allocated with a size rounded to the next power + * of 2 + */ + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + /* By default, no element should be set */ + EXPECT_FALSE (bitmap_is_set (bitmap, 0)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 0)); + + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + EXPECT_FALSE (bitmap_is_set (bitmap, size_not_pow2 - 1)); + EXPECT_TRUE (bitmap_is_unset (bitmap, size_not_pow2 - 1)); + + /* Bitmap should not have been reallocated */ + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + /* After setting a bit after the end, bitmap should have been reallocated */ + bitmap_set (bitmap, sizeof (bitmap[0]) * 8 - 1); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + /* After setting a bit after the end, bitmap should have been reallocated */ + rc = bitmap_set (bitmap, sizeof (bitmap[0]) * 8); + EXPECT_GE (rc, 0); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 2UL); + + rc = bitmap_set (bitmap, sizeof (bitmap[0]) * 8 + 1); + EXPECT_GE (rc, 0); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 2UL); + + bitmap_free (bitmap); + + size_t size_pow2 = 16; + + /* Limiting test for allocation size */ + bitmap_init (bitmap, size_pow2, 0); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + bitmap_set (bitmap, 20); + EXPECT_TRUE (bitmap_is_set (bitmap, 20)); + EXPECT_FALSE (bitmap_is_unset (bitmap, 20)); + EXPECT_FALSE (bitmap_is_set (bitmap, 19)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 19)); + + // Test edge cases (i.e. start and end of block) + off_t start_position = 0; + bitmap_set (bitmap, start_position); + EXPECT_TRUE (bitmap_is_set (bitmap, start_position)); + EXPECT_FALSE (bitmap_is_unset (bitmap, start_position)); + + off_t end_position = BITMAP_WIDTH (bitmap) - 1; + bitmap_set (bitmap, end_position); + EXPECT_TRUE (bitmap_is_set (bitmap, end_position)); + EXPECT_FALSE (bitmap_is_unset (bitmap, end_position)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapUnSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + bitmap_set (bitmap, 20); + bitmap_set (bitmap, 19); + bitmap_unset (bitmap, 20); + EXPECT_FALSE (bitmap_is_set (bitmap, 20)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 20)); + EXPECT_TRUE (bitmap_is_set (bitmap, 19)); + EXPECT_FALSE (bitmap_is_unset (bitmap, 19)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapSetTo) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + bitmap_set_to (bitmap, 40); + EXPECT_TRUE (bitmap_is_set (bitmap, 20)); + EXPECT_TRUE (bitmap_is_set (bitmap, 21)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 41)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 42)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapFirstSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get first set bit. It should be INVALID_INDEX + EXPECT_EQ (bitmap_first_set (bitmap), BITMAP_INVALID_INDEX); + + // set bit 40 + bitmap_set (bitmap, 40); + EXPECT_TRUE (bitmap_is_set (bitmap, 40)); + + // Get first set bit. It should be bit 40 (surprise):) + EXPECT_EQ (bitmap_first_set (bitmap), hicn_uword (40)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // The first set bit now should be bit #3 + EXPECT_EQ (bitmap_first_set (bitmap), hicn_uword (3)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapFirstUnSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get first unset bit. It should be 0 + EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (0)); + + // set bit 0 + bitmap_set (bitmap, 0); + EXPECT_TRUE (bitmap_is_set (bitmap, 0)); + + // Get first unset bit. It should be bit 1 + EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (1)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // The first set bit now should be still 1 + EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (1)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapNextSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get next unset bit >= 0. It should be INVALID + EXPECT_EQ (bitmap_next_set (bitmap, 0), BITMAP_INVALID_INDEX); + + // set bit 0 + bitmap_set (bitmap, 0); + EXPECT_TRUE (bitmap_is_set (bitmap, 0)); + + // Get next set bit >= 0. It should be bit 0 + EXPECT_EQ (bitmap_next_set (bitmap, 0), hicn_uword (0)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // Get next set bit >= 1. It should be 3 + EXPECT_EQ (bitmap_next_set (bitmap, 1), hicn_uword (3)); + + // set (N-2)th bit + bitmap_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2); + EXPECT_TRUE (bitmap_is_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2)); + EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 3), + DEFAULT_SIZE * WORD_WIDTH - 2); + + // set (N-1)th bit + bitmap_unset (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2); + bitmap_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1); + EXPECT_TRUE (bitmap_is_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1)); + EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2), + DEFAULT_SIZE * WORD_WIDTH - 1); + EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1), + DEFAULT_SIZE * WORD_WIDTH - 1); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapNextUnSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get next unset bit >= 0. It should be 0 + EXPECT_EQ (bitmap_next_unset (bitmap, 0), hicn_uword (0)); + + // set bit 0 + bitmap_set (bitmap, 0); + EXPECT_TRUE (bitmap_is_set (bitmap, 0)); + + // Get next set bit >= 0. It should be bit 1 + EXPECT_EQ (bitmap_next_unset (bitmap, 0), hicn_uword (1)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // Get next unset bit after 3. It should be 4 + EXPECT_EQ (bitmap_next_unset (bitmap, 3), hicn_uword (4)); + + bitmap_free (bitmap); +} diff --git a/lib/src/test/test_interest_manifest.cc b/lib/src/test/test_interest_manifest.cc new file mode 100644 index 000000000..c912b0bc6 --- /dev/null +++ b/lib/src/test/test_interest_manifest.cc @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +extern "C" +{ +#include <hicn/interest_manifest.h> +} + +static constexpr hicn_uword WORD_SIZE = WORD_WIDTH; + +class InterestManifestTest : public ::testing::Test +{ +protected: + InterestManifestTest () {} + virtual ~InterestManifestTest () {} +}; + +TEST_F (InterestManifestTest, OneWordBitmapUpdate) +{ + hicn_uword initial_bitmap[1]; + hicn_uword curr_bitmap[1] = { 0 }; + initial_bitmap[0] = + 0x0000000000000b07; // ...000000000000000000000101100000111 + + // Consume first 4 'one' bits (i.e. suffixes), reaching position 9 + size_t pos = 0, max_suffixes = 4; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap, pos, + WORD_SIZE, max_suffixes); + EXPECT_EQ (pos, std::size_t (9)); + EXPECT_EQ (curr_bitmap[0], hicn_uword (0x0000000000000107)); + + // Consume the remaining 2 'one' bits, reaching end of bitmap + hicn_uword curr_bitmap2[1] = { 0 }; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap2, pos, + WORD_SIZE, max_suffixes); + EXPECT_EQ (pos, WORD_SIZE); + EXPECT_EQ (curr_bitmap2[0], hicn_uword (0x00000a00)); + + // Consume all suffixes at once + hicn_uword curr_bitmap3[1] = { 0 }; + max_suffixes = 16; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap3, 0, + WORD_SIZE, max_suffixes); + EXPECT_EQ (pos, WORD_SIZE); + EXPECT_EQ (curr_bitmap3[0], initial_bitmap[0]); +} + +TEST_F (InterestManifestTest, TwoWordBitmapUpdate) +{ + hicn_uword initial_bitmap[2]; + initial_bitmap[0] = 0x0000000000000b07; + initial_bitmap[1] = 0x0000000000000b07; + // -> 0000000000000000000010110000011100000000000000000000101100000111 + + int expected_pos[] = { WORD_SIZE + 2, 2 * WORD_SIZE }; + u32 expected_bitmap[][2] = { { 0x00000b07, 0x00000003 }, + { 0x0, 0x00000b04 } }; + + // Loop to consume all suffixes + int pos = 0, max_suffixes = 8, i = 0, len = WORD_SIZE * 2; + while (pos != len) + { + hicn_uword curr_bitmap[2] = { 0 }; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap, pos, + len, max_suffixes); + + EXPECT_EQ (pos, expected_pos[i]); + EXPECT_EQ (curr_bitmap[0], expected_bitmap[i][0]); + EXPECT_EQ (curr_bitmap[1], expected_bitmap[i][1]); + i++; + } +}
\ No newline at end of file diff --git a/lib/src/test/test_khash.cc b/lib/src/test/test_khash.cc new file mode 100644 index 000000000..b0423ab5d --- /dev/null +++ b/lib/src/test/test_khash.cc @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#include <hicn/util/khash.h> +} + +KHASH_MAP_INIT_INT (int, unsigned char) + +typedef struct +{ + unsigned key; + unsigned char val; +} int_unpack_t; + +typedef struct +{ + unsigned key; + unsigned char val; +} __attribute__ ((__packed__)) int_packed_t; + +#define hash_eq(a, b) ((a).key == (b).key) +#define hash_func(a) ((a).key) + +KHASH_INIT (iun, int_unpack_t, char, 0, hash_func, hash_eq) +KHASH_INIT (ipk, int_packed_t, char, 0, hash_func, hash_eq) + +class KHashTest : public ::testing::Test +{ +protected: + KHashTest () {} + + virtual ~KHashTest () + { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + virtual void + SetUp () + { + khash = kh_init (int); + } + + virtual void + TearDown () + { + kh_destroy (int, khash); + } + khash_t (int) * khash; +}; + +TEST_F (KHashTest, KhashIntSize) +{ + int ret; + int k; + int size = kh_size (khash); + + EXPECT_EQ (size, 0); + k = kh_put (int, khash, 10, &ret); + if (ret == 1) + { + kh_val (khash, k) = 10; + } + size = kh_size (khash); + EXPECT_EQ (size, 1); +} + +TEST_F (KHashTest, KhashIntPut) +{ + int ret; + int k; + k = kh_put (int, khash, 10, &ret); + if (ret == 1) + { + kh_val (khash, k) = 10; + } + int size = kh_size (khash); + EXPECT_EQ (size, 1); + k = kh_put (int, khash, 20, &ret); + if (ret == 1) + { + kh_val (khash, k) = 20; + } + size = kh_size (khash); + EXPECT_EQ (size, 2); +} + +TEST_F (KHashTest, KhashCheckValue) +{ + int ret; + int k; + k = kh_put (int, khash, 10, &ret); + if (ret == 1) + { + kh_val (khash, k) = 100; + } + k = kh_put (int, khash, 20, &ret); + if (ret == 1) + { + kh_val (khash, k) = 200; + } + + k = kh_put (int, khash, 10, &ret); + int val = -1; + if (!ret) + val = kh_val (khash, k); + EXPECT_EQ (val, 100); + + k = kh_put (int, khash, 20, &ret); + val = -1; + if (!ret) + val = kh_val (khash, k); + EXPECT_EQ (val, 200); +} + +// Check that there are no collisions in case of same key hash +typedef struct +{ + int x; +} Key; +#define hash_key(key) 1 // Hash is always 1 to simulate collisions +#define key_hash_eq(a, b) (a->x == b->x) // Function used in case of collisions +KHASH_INIT (test_map, const Key *, unsigned, 1, hash_key, key_hash_eq); + +TEST_F (KHashTest, Collisions) +{ + int ret; + khiter_t k; + + kh_test_map_t *map = kh_init (test_map); + Key key1 = { .x = 10 }; + Key key2 = { .x = 11 }; + + k = kh_put_test_map (map, &key1, &ret); + EXPECT_EQ (ret, 1); + kh_val (map, k) = 15; + + k = kh_put_test_map (map, &key2, &ret); + EXPECT_EQ (ret, 1); + kh_val (map, k) = 27; + + k = kh_get_test_map (map, &key1); + ASSERT_NE (k, kh_end (map)); + unsigned val = kh_val (map, k); + EXPECT_EQ (val, 15u); + + k = kh_get_test_map (map, &key2); + ASSERT_NE (k, kh_end (map)); + val = kh_val (map, k); + EXPECT_EQ (val, 27u); + + kh_destroy_test_map (map); +} diff --git a/lib/src/test/test_name.cc b/lib/src/test/test_name.cc index 207725adb..35e636b63 100644 --- a/lib/src/test/test_name.cc +++ b/lib/src/test/test_name.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -58,32 +58,24 @@ protected: // The hash should be equal, with and without considering the suffix uint32_t hash_a, hash_b; - rc = hicn_name_hash (&name_a, &hash_a, 1); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 1); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_hash (&name_a); + hash_b = hicn_name_get_hash (&name_b); EXPECT_EQ (hash_a, hash_b); - rc = hicn_name_hash (&name_a, &hash_a, 0); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 0); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_prefix_hash (&name_a); + hash_b = hicn_name_get_prefix_hash (&name_b); EXPECT_EQ (hash_a, hash_b); // Now let's change the suffix - rc = hicn_name_set_seq_number (&name_a, 97531); + rc = hicn_name_set_suffix (&name_a, 97531); // They should result equal if we do not consider the suffix - rc = hicn_name_hash (&name_a, &hash_a, 0); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 0); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_prefix_hash (&name_a); + hash_b = hicn_name_get_prefix_hash (&name_b); EXPECT_EQ (hash_a, hash_b); // And different if we consider it - rc = hicn_name_hash (&name_a, &hash_a, 1); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 1); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_hash (&name_a); + hash_b = hicn_name_get_hash (&name_b); EXPECT_NE (hash_a, hash_b); } @@ -120,7 +112,7 @@ protected: EXPECT_EQ (rc, 0); // Now let's change the suffix - rc = hicn_name_set_seq_number (&name_a, 97531); + rc = hicn_name_set_suffix (&name_a, 97531); // They should result equal if we do not consider the suffix rc = hicn_name_compare (&name_a, &name_b, 0); EXPECT_EQ (rc, 0); @@ -130,13 +122,13 @@ protected: } void - nameFromIpPrefixTest (const ip_prefix_t &ip_prefix) + nameFromIpPrefixTest (const hicn_ip_prefix_t &hicn_ip_prefix) { uint32_t suffix = 54321; hicn_name_t name; - int rc = hicn_name_create_from_ip_prefix (&ip_prefix, suffix, &name); + int rc = hicn_name_create_from_ip_prefix (&hicn_ip_prefix, suffix, &name); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); - rc = memcmp (ip_prefix.address.v6.as_u8, name.prefix.v6.as_u8, + rc = memcmp (hicn_ip_prefix.address.v6.as_u8, name.prefix.v6.as_u8, sizeof (name.prefix.v6)); EXPECT_EQ (rc, 0); EXPECT_EQ (suffix, name.suffix); @@ -154,16 +146,16 @@ protected: int family; rc = hicn_name_get_family (&name, &family); - ip_prefix_t ip_prefix; - rc = hicn_name_to_ip_prefix (&name, &ip_prefix); + hicn_ip_prefix_t hicn_ip_prefix; + rc = hicn_name_to_hicn_ip_prefix (&name, &hicn_ip_prefix); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); - EXPECT_EQ (ip_prefix.family, family); - rc = ip_address_cmp (&ip_prefix.address, &name.prefix, AF_INET6); + EXPECT_EQ (hicn_ip_prefix.family, family); + rc = hicn_ip_address_cmp (&hicn_ip_prefix.address, &name.prefix); EXPECT_EQ (rc, 0); } hicn_name_t name_, name4_, name6_; - ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; + hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; }; /** @@ -180,7 +172,7 @@ TEST_F (NameTest, NameInitialization) EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check name is correctly created - rc = ip_address_cmp (&name6.prefix, &ipv6_prefix_bytes, AF_INET6); + rc = hicn_ip_address_cmp (&name6.prefix, &ipv6_prefix_bytes); EXPECT_EQ (rc, 0); EXPECT_EQ (name6.suffix, suffix); @@ -190,7 +182,7 @@ TEST_F (NameTest, NameInitialization) EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check name is correctly created - rc = ip_address_cmp (&name4.prefix, &ipv4_prefix_bytes, AF_INET); + rc = hicn_ip_address_cmp (&name4.prefix, &ipv4_prefix_bytes); EXPECT_EQ (name4.prefix.pad[0], 0UL); EXPECT_EQ (name4.prefix.pad[1], 0UL); EXPECT_EQ (name4.prefix.pad[2], 0UL); @@ -202,7 +194,7 @@ TEST_F (NameTest, NameInitialization) EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check name is correctly created - rc = ip_address_cmp (&name6.prefix, &ipv4_prefix_bytes, AF_INET); + rc = hicn_ip_address_cmp (&name6.prefix, &ipv4_prefix_bytes); EXPECT_EQ (name6.prefix.pad[0], 0UL); EXPECT_EQ (name6.prefix.pad[1], 0UL); EXPECT_EQ (name6.prefix.pad[2], 0UL); @@ -215,22 +207,26 @@ TEST_F (NameTest, NameInitialization) */ TEST_F (NameTest, NameFromIpPrefix6) { - ip_prefix_t ip_prefix = { .family = AF_INET6, .address = {}, .len = 64 }; + hicn_ip_prefix_t hicn_ip_prefix = { .family = AF_INET6, + .address = {}, + .len = 64 }; - ip_prefix.address.v6.as_u64[0] = ipv6_prefix_bytes.v6.as_u64[0]; - ip_prefix.address.v6.as_u64[1] = ipv6_prefix_bytes.v6.as_u64[1]; + hicn_ip_prefix.address.v6.as_u64[0] = ipv6_prefix_bytes.v6.as_u64[0]; + hicn_ip_prefix.address.v6.as_u64[1] = ipv6_prefix_bytes.v6.as_u64[1]; - nameFromIpPrefixTest (ip_prefix); + nameFromIpPrefixTest (hicn_ip_prefix); } TEST_F (NameTest, NameFromIpPrefix4) { - ip_prefix_t ip_prefix = { .family = AF_INET, .address = {}, .len = 64 }; - ip_prefix.address.v4.as_u32 = ipv4_prefix_bytes.v4.as_u32; - ip_prefix.address.pad[0] = 0; - ip_prefix.address.pad[1] = 0; - ip_prefix.address.pad[2] = 0; - nameFromIpPrefixTest (ip_prefix); + hicn_ip_prefix_t hicn_ip_prefix = { .family = AF_INET, + .address = {}, + .len = 64 }; + hicn_ip_prefix.address.v4.as_u32 = ipv4_prefix_bytes.v4.as_u32; + hicn_ip_prefix.address.pad[0] = 0; + hicn_ip_prefix.address.pad[1] = 0; + hicn_ip_prefix.address.pad[2] = 0; + nameFromIpPrefixTest (hicn_ip_prefix); } TEST_F (NameTest, NameCompare6) { nameCompareTest (ipv6_prefix); } @@ -257,8 +253,8 @@ TEST_F (NameTest, NameCopy4) { nameCopyTest (ipv4_prefix); } TEST_F (NameTest, NameCopyToDestination) { - ip4_address_t dst4; - ip6_address_t dst6; + ipv4_address_t dst4; + ipv6_address_t dst6; // Copy names to destination int rc = hicn_name_copy_prefix_to_destination (dst4.as_u8, &name4_); @@ -282,7 +278,7 @@ TEST_F (NameTest, SetGetSuffix) EXPECT_EQ (suffix, suffix_ret); // Set new suffix - rc = hicn_name_set_seq_number (&name6_, suffix2); + rc = hicn_name_set_suffix (&name6_, suffix2); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check suffix was set diff --git a/lib/src/test/test_new_header.cc b/lib/src/test/test_new_header.cc index 33c9e13c9..c936b6910 100644 --- a/lib/src/test/test_new_header.cc +++ b/lib/src/test/test_new_header.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,10 +20,10 @@ extern "C" #include <hicn/name.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/protocol/new.h> -#include <hicn/protocol/ah.h> -#include <hicn/header.h> -#include <hicn/compat.h> +#include <hicn/packet.h> + +#include "../protocol/ah.h" +#include "../protocol/new.h" } class NewHeaderTest : public ::testing::Test @@ -33,10 +33,11 @@ protected: const char *ipv4_prefix = "12.13.14.15"; const uint32_t suffix = 12345; - NewHeaderTest (size_t hdr_size, hicn_format_t format) - : buffer_ (new uint8_t[hdr_size]), header_ ((hicn_header_t *) (buffer_)), + NewHeaderTest (hicn_packet_format_t format) + : buffer_ (new uint8_t[NEW_HDRLEN]), format_ (format), name_{}, name4_{}, name6_{} { + int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6); EXPECT_EQ (rc, 1); @@ -49,42 +50,46 @@ protected: EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); } - NewHeaderTest () : NewHeaderTest (NEW_HDRLEN, HF_NEW) {} + NewHeaderTest () : NewHeaderTest (HICN_PACKET_FORMAT_NEW) {} virtual ~NewHeaderTest () { delete[] buffer_; } void - checkCommon (const _new_header_t *new_hdr) + checkCommon () { // Initialize header - int rc = hicn_packet_init_header (format_, header_); + hicn_packet_set_format (&pkbuf_, format_); + // pkbuf_set_type (&pkbuf_, HICN_PACKET_TYPE_UNDEFINED); + int rc = hicn_packet_init_header (&pkbuf_, 0); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); + auto new_hdr = (_new_header_t *) buffer_; + // Check fields EXPECT_EQ (new_hdr->prefix.v6.as_u64[0], 0UL); EXPECT_EQ (new_hdr->prefix.v6.as_u64[1], 0UL); EXPECT_EQ (new_hdr->suffix, 0UL); EXPECT_EQ (new_hdr->lifetime, 0UL); EXPECT_EQ (new_hdr->path_label, 0UL); - EXPECT_EQ (new_hdr->payload_length, 0UL); + EXPECT_EQ (new_hdr->payload_len, 0UL); EXPECT_EQ (_get_new_header_version (new_hdr), 0x9); + EXPECT_EQ (new_hdr->flags, 0); } virtual void SetUp () override { - auto new_hdr = &header_->protocol.newhdr; - checkCommon (new_hdr); - EXPECT_EQ (new_hdr->flags, 0); + checkCommon (); } uint8_t *buffer_; - hicn_header_t *header_; - hicn_format_t format_; + hicn_packet_buffer_t pkbuf_; + hicn_packet_format_t format_; hicn_name_t name_, name4_, name6_; - ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; + hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; }; +#if 0 class NewHeaderAHTest : public NewHeaderTest { protected: @@ -229,7 +234,7 @@ TEST_F (NewHeaderTest, SetGetName) TEST_F (NewHeaderTest, SetGetLocator) { // This function does nothing but it is set for compatibility - ip_address_t locator; + hicn_ip_address_t locator; memset (&locator, 0, sizeof (locator)); locator.v6.as_u8[15] = 1; int rc = hicn_packet_set_interest (format_, header_); @@ -338,3 +343,4 @@ TEST_F (NewHeaderTest, SetGetPayloadType) EXPECT_EQ (payload_type, payload_type_ret); } +#endif diff --git a/lib/src/test/test_pool.cc b/lib/src/test/test_pool.cc new file mode 100644 index 000000000..cbb5ce068 --- /dev/null +++ b/lib/src/test/test_pool.cc @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#define WITH_TESTS +#include <hicn/util/pool.h> +} + +/* + * TODO + * - test max_size + */ + +#define DEFAULT_SIZE 10 + +class PoolTest : public ::testing::Test +{ +protected: + PoolTest () {} + virtual ~PoolTest () {} + + int *pool; +}; + +TEST_F (PoolTest, PoolAllocation) +{ + int rc; + + pool_init (pool, DEFAULT_SIZE, 0); + + size_t pool_size = next_pow2 (DEFAULT_SIZE); + + EXPECT_EQ (pool_get_alloc_size (pool), pool_size); + + /* Check that free indices and bitmaps are correctly initialize */ + off_t *fi = pool_get_free_indices (pool); + EXPECT_EQ (vector_len (fi), pool_size); + EXPECT_EQ (fi[0], (long) (pool_size - 1)); + EXPECT_EQ (fi[pool_size - 1], 0); + + /* The allocated size of the underlying vector should be the next power of + * two + */ + EXPECT_EQ (vector_get_alloc_size (fi), pool_size); + + bitmap_t *fb = pool_get_free_bitmap (pool); + EXPECT_TRUE (bitmap_is_set (fb, 0)); + EXPECT_TRUE (bitmap_is_set (fb, pool_size - 2)); + EXPECT_TRUE (bitmap_is_set (fb, pool_size - 1)); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size)); + + /* Getting elements from the pool should correctly update the free indices + * and bitmap */ + int *elt; + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), pool_size - 1); + EXPECT_TRUE (bitmap_is_unset (fb, 0)); + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), pool_size - 2); + EXPECT_TRUE (bitmap_is_unset (fb, 1)); + + for (unsigned i = 0; i < pool_size - 4; i++) + { + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + } + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), 1UL); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 2)); + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), 0UL); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 1)); + + /* + * Getting elements within the allocated range should not have triggered a + * resize + */ + EXPECT_EQ (pool_len (pool), pool_size); + + /* + * Getting elements once the allocated range has been exceeded should + * trigger a resize + */ + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + + EXPECT_EQ (pool_get_alloc_size (pool), pool_size * 2); + + EXPECT_EQ (pool_len (pool), pool_size + 1); + + /* + * Doubling the size, we should have again pool_size elements free, minus 1 + */ + EXPECT_EQ (pool_get_free_indices_size (pool), pool_size - 1); + + /* + * NOTE: this is wrong as there has been a realloc and the old fi + * pointer is now invalid + */ + // EXPECT_EQ(vector_len(fi), pool_size - 1); + + /* And the bitmap should also be correctly modified */ + fb = pool_get_free_bitmap (pool); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size)); + + /* Check that surrounding values are also correct */ + EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 1)); + EXPECT_TRUE (bitmap_is_set (fb, pool_size + 1)); + + /* Setting elements after should through */ + + /* Check that free indices and bitmaps are correctly updated */ + + pool_free (pool); +} + +TEST_F (PoolTest, PoolPut) +{ + pool_init (pool, DEFAULT_SIZE, 0); + + int *elt; + pool_get (pool, elt); + *elt = 10; + pool_put (pool, elt); + + pool_free (pool); +} + +TEST_F (PoolTest, PoolGetForceBitmapRealloc) +{ + const int N = 64; + int *elts[N]; + int *elt = NULL; + pool_init (pool, N, 0); + + for (int i = 0; i < N; i++) + pool_get (pool, elts[i]); + pool_get (pool, elt); + + pool_free (pool); +} + +TEST_F (PoolTest, PoolGetAfterReleasing) +{ + int *elt1 = NULL, *elt2 = NULL, *tmp = NULL; + pool_init (pool, DEFAULT_SIZE, 0); + + // If two elements are requested... + off_t id1 = pool_get (pool, elt1); + pool_get (pool, tmp); + + // ...and the first one is released... + pool_put (pool, elt1); + + // ...requesting a new one should return + // the first one (that was freed) + off_t id2 = pool_get (pool, elt2); + EXPECT_EQ (id1, id2); + EXPECT_EQ (elt1, elt2); + + pool_free (pool); +} + +TEST_F (PoolTest, PoolGetMultipleElementsAfterReleasing) +{ + const int N = 2; + int *elts[N]; + pool_init (pool, N, 0); + + for (int i = 0; i < N; i++) + pool_get (pool, elts[i]); + for (int i = 0; i < N; i++) + pool_put (pool, elts[i]); + for (int i = 0; i < N; i++) + pool_get (pool, elts[i]); + + pool_free (pool); +} diff --git a/lib/src/test/test_ring.cc b/lib/src/test/test_ring.cc new file mode 100644 index 000000000..f0b0371e8 --- /dev/null +++ b/lib/src/test/test_ring.cc @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#define WITH_TESTS +#include <hicn/util/ring.h> +} + +#define DEFAULT_SIZE 10UL + +class RingTest : public ::testing::Test +{ +protected: + RingTest () { ring_init (ring, DEFAULT_SIZE); } + virtual ~RingTest () { ring_free (ring); } + + int *ring = NULL; +}; + +/* TEST: Ring allocation and initialization */ +TEST_F (RingTest, RingAddOne) +{ + int val = -1; + /* Allocated size should be the next power of two */ + EXPECT_EQ (ring_get_size (ring), 0UL); + ring_add_value (ring, 1); + EXPECT_EQ (ring_get_size (ring), 1UL); + ring_get (ring, 0, &val); + EXPECT_EQ (val, 1); + EXPECT_EQ (ring_get_size (ring), 1UL); + ring_advance (ring, 1); + EXPECT_EQ (ring_get_size (ring), 0UL); +} + +TEST_F (RingTest, RingAddMany) +{ + size_t i = 0; + int val = -1; + size_t count = 0; + + /* Allocated size should be the next power of two */ + EXPECT_EQ (ring_get_size (ring), 0UL); + for (unsigned i = 0; i < DEFAULT_SIZE; i++) + ring_add_value (ring, i); + EXPECT_EQ (ring_get_size (ring), DEFAULT_SIZE); + + count = 0; + ring_enumerate_n (ring, i, &val, 1, { + EXPECT_EQ (val, (int) (i)); + count++; + }); + EXPECT_EQ (count, 1UL); + + count = 0; + ring_enumerate_n (ring, i, &val, DEFAULT_SIZE, { + EXPECT_EQ (val, (int) (i)); + count++; + }); + EXPECT_EQ (count, DEFAULT_SIZE); + + count = 0; + ring_enumerate_n (ring, i, &val, DEFAULT_SIZE + 1, { + EXPECT_EQ (val, (int) (i)); + count++; + }); + EXPECT_EQ (count, DEFAULT_SIZE); + + // Drop one + ring_add_value (ring, DEFAULT_SIZE); + EXPECT_EQ (ring_get_size (ring), DEFAULT_SIZE); + + count = 0; + ring_enumerate_n (ring, i, &val, DEFAULT_SIZE, { + EXPECT_EQ (val, (int) (i + 1)); // all values shoud be shifted + count++; + }); + EXPECT_EQ (count, DEFAULT_SIZE); + + ring_advance (ring, DEFAULT_SIZE); + EXPECT_EQ (ring_get_size (ring), 0UL); +} diff --git a/lib/src/test/test_udp_header.cc b/lib/src/test/test_udp_header.cc index 5d9f4d1eb..2853ee31b 100644 --- a/lib/src/test/test_udp_header.cc +++ b/lib/src/test/test_udp_header.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,10 +20,12 @@ extern "C" #include <hicn/name.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/protocol/new.h> -#include <hicn/protocol/ah.h> -#include <hicn/header.h> -#include <hicn/compat.h> +#include <hicn/packet.h> + +#include "../protocol/ah.h" +#include "../protocol/ipv6.h" +#include "../protocol/udp.h" +#include "../protocol/new.h" } class UdpHeaderTest : public ::testing::Test @@ -33,8 +35,8 @@ protected: const char *ipv4_prefix = "12.13.14.15"; const uint32_t suffix = 12345; - UdpHeaderTest (size_t hdr_size, hicn_format_t format) - : buffer_ (new uint8_t[hdr_size]), header_ ((hicn_header_t *) (buffer_)), + UdpHeaderTest (size_t hdr_size, hicn_packet_format_t format) + : buffer_ (new uint8_t[hdr_size]), hdr_size_ (hdr_size), format_ (format), name_{}, name4_{}, name6_{} { int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6); @@ -50,19 +52,26 @@ protected: } UdpHeaderTest () - : UdpHeaderTest (NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, HF_INET6_UDP) + : UdpHeaderTest (NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, + HICN_PACKET_FORMAT_IPV6_UDP) { } virtual ~UdpHeaderTest () { delete[] buffer_; } + // checked everytime we build the packet... void - checkCommon (const _ipv6_header_t *ip6_hdr) + checkCommon () { - // Initialize header - int rc = hicn_packet_init_header (format_, header_); + /* Initialize packet buffer headers */ + hicn_packet_set_format (&pkbuf_, format_); + hicn_packet_set_type (&pkbuf_, HICN_PACKET_TYPE_INTEREST); + hicn_packet_set_buffer (&pkbuf_, buffer_, hdr_size_, 0); + int rc = hicn_packet_init_header (&pkbuf_, 0); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); + auto ip6_hdr = (_ipv6_header_t *) buffer_; + // Check fields EXPECT_EQ (ip6_hdr->saddr.as_u64[0], 0UL); EXPECT_EQ (ip6_hdr->saddr.as_u64[1], 0UL); @@ -82,22 +91,22 @@ protected: EXPECT_EQ (new_hdr->suffix, 0UL); EXPECT_EQ (new_hdr->lifetime, 0UL); EXPECT_EQ (new_hdr->path_label, 0UL); - EXPECT_EQ (new_hdr->payload_length, 0UL); + EXPECT_EQ (new_hdr->payload_len, 0UL); EXPECT_EQ (_get_new_header_version (new_hdr), 0x9); } virtual void SetUp () override { - auto ip6_hdr = &header_->protocol.ipv6; - checkCommon (ip6_hdr); + checkCommon (); } uint8_t *buffer_; - hicn_header_t *header_; - hicn_format_t format_; + size_t hdr_size_; + hicn_packet_buffer_t pkbuf_; + hicn_packet_format_t format_; hicn_name_t name_, name4_, name6_; - ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; + hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; }; class UdpHeaderAHTest : public UdpHeaderTest @@ -105,7 +114,7 @@ class UdpHeaderAHTest : public UdpHeaderTest protected: UdpHeaderAHTest () : UdpHeaderTest (AH_HDRLEN + NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, - HF_INET6_UDP_AH) + HICN_PACKET_FORMAT_IPV6_UDP_AH) { } }; @@ -115,26 +124,21 @@ protected: */ TEST_F (UdpHeaderTest, GetFormat) { - // Get format from existing packet - hicn_format_t format; - int rc = hicn_packet_get_format (header_, &format); - EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); - - // Check it corresponds to the new header format - EXPECT_EQ (format, HF_INET6_UDP); + hicn_packet_format_t format = hicn_packet_get_format (&pkbuf_); + EXPECT_EQ (format.as_u32, HICN_PACKET_FORMAT_IPV6_UDP.as_u32); } TEST_F (UdpHeaderAHTest, GetFormat) { // Get format from existing packet - hicn_format_t format; - int rc = hicn_packet_get_format (header_, &format); - EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); + hicn_packet_format_t format = hicn_packet_get_format (&pkbuf_); // Check it corresponds to the new header format - EXPECT_EQ (format, HF_INET6_UDP_AH); + EXPECT_EQ (format.as_u32, HICN_PACKET_FORMAT_IPV6_UDP_AH.as_u32); } +#if 0 + // /** // * @brief Checksum functions are not required, but we keep them for // * compatibility. @@ -244,7 +248,7 @@ TEST_F (UdpHeaderTest, SetGetName) TEST_F (UdpHeaderTest, SetGetLocator) { // This function does nothing but it is set for compatibility - ip_address_t locator; + hicn_ip_address_t locator; memset (&locator, 0, sizeof (locator)); locator.v6.as_u8[15] = 1; int rc = hicn_packet_set_interest (format_, header_); @@ -353,3 +357,4 @@ TEST_F (UdpHeaderTest, SetGetPayloadType) EXPECT_EQ (payload_type, payload_type_ret); } +#endif diff --git a/lib/src/test/test_vector.cc b/lib/src/test/test_vector.cc new file mode 100644 index 000000000..88b0bb7cf --- /dev/null +++ b/lib/src/test/test_vector.cc @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +extern "C" +{ +#include <hicn/util/vector.h> +} + +static constexpr size_t DEFAULT_SIZE = 10; +static constexpr size_t N_ELEMENTS = 5; + +class VectorTest : public ::testing::Test +{ +protected: + VectorTest () { vector_init (vector, DEFAULT_SIZE, 0); } + virtual ~VectorTest () { vector_free (vector); } + + int *vector = NULL; +}; + +TEST_F (VectorTest, VectorAllocateAndResize) +{ + // Allocated size should be the next power of two + EXPECT_EQ (vector_get_alloc_size (vector), 16UL); + + // Setting elements within the allocated size should not trigger a resize + vector_ensure_pos (vector, 15); + EXPECT_EQ (vector_get_alloc_size (vector), 16UL); + + // Setting elements after should through + vector_ensure_pos (vector, 16); + EXPECT_EQ (vector_get_alloc_size (vector), 32UL); +} + +TEST_F (VectorTest, VectorSize) +{ + EXPECT_EQ (vector_len (vector), size_t (0)); + + // Check size after pushing one element + vector_push (vector, 1); + EXPECT_EQ (vector_len (vector), size_t (1)); + + // Check size after pushing additional elements + vector_push (vector, 2); + vector_push (vector, 3); + EXPECT_EQ (vector_len (vector), size_t (3)); + + // Try adding multiple elements + const int n_elements_to_add = 5; + size_t expected_new_len = vector_len (vector) + n_elements_to_add; + for (int i = 0; i < n_elements_to_add; i++) + vector_push (vector, i); + EXPECT_EQ (vector_len (vector), expected_new_len); +} + +TEST_F (VectorTest, VectorCheckValue) +{ + // Add elements + vector_push (vector, 109); + vector_push (vector, 200); + EXPECT_EQ (vector_at (vector, 0), 109); + EXPECT_EQ (vector_at (vector, 1), 200); + + // Update element + vector_set (vector, 1, 400); + EXPECT_EQ (vector_at (vector, 1), 400); + + // Add at last available position + size_t prev_size = vector_len (vector); + vector_set (vector, vector_len (vector) - 1, 123); + EXPECT_EQ (vector_at (vector, vector_len (vector) - 1), 123); + EXPECT_EQ (prev_size, vector_len (vector)) << "Size should not have changed"; +} + +TEST_F (VectorTest, RemoveElement) +{ + // Populate vector + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + EXPECT_EQ (vector_len (vector), N_ELEMENTS); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_EQ (vector_at (vector, i), (int) i); + + // Remove element + int value_to_remove = 3; + int num_removed = vector_remove_unordered (vector, value_to_remove); + + EXPECT_EQ (vector_len (vector), N_ELEMENTS - 1); + EXPECT_EQ (num_removed, 1); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_NE (vector_at (vector, i), value_to_remove); +} + +TEST_F (VectorTest, RemoveNonExistingElement) +{ + // Push some initial values + vector_push (vector, 1); + vector_push (vector, 2); + vector_push (vector, 3); + EXPECT_EQ (vector_len (vector), size_t (3)); + + // Remove non-existing element + int num_removed = vector_remove_unordered (vector, 5); + EXPECT_EQ (num_removed, 0); + size_t prev_size = vector_len (vector); + EXPECT_EQ (prev_size, vector_len (vector)) << "Size should not have changed"; +} + +TEST_F (VectorTest, RemoveDuplicatedElement) +{ + // Populate vector + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + EXPECT_EQ (vector_len (vector), N_ELEMENTS); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_EQ (vector_at (vector, i), (int) i); + vector_set (vector, 0, 3); // Duplicate element + + // Remove (duplicated) elements + int value_to_remove = 3; + int num_removed = vector_remove_unordered (vector, value_to_remove); + + EXPECT_EQ (vector_len (vector), N_ELEMENTS - 2); + EXPECT_EQ (num_removed, 2); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_NE (vector_at (vector, i), value_to_remove); +} + +TEST_F (VectorTest, Iterate) +{ + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + + int count = 0; + int *elem; + vector_foreach (vector, elem, { EXPECT_EQ (*elem, count++); }); +} + +TEST_F (VectorTest, MultipleResize) +{ + // Use small vector (size=1) to force multiple realloc operations + int *small_vector; + vector_init (small_vector, 1, 0); + + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (small_vector, i); + + for (size_t i = 0; i < N_ELEMENTS; i++) + EXPECT_EQ (vector_at (small_vector, i), (int) i); + + EXPECT_EQ (vector_len (small_vector), 5UL); + EXPECT_EQ (vector_get_alloc_size (small_vector), 8UL); + + vector_free (small_vector); +} + +TEST_F (VectorTest, MaxSize) +{ + const int max_size = 4; + + // Fill the vector until max size is reached + int *small_vector; + vector_init (small_vector, 2, max_size); + for (int i = 0; i < max_size; i++) + vector_push (small_vector, i); + + // Try expanding or appending elements should fail + int rc = vector_ensure_pos (small_vector, max_size); + EXPECT_EQ (rc, -1); + rc = vector_push (small_vector, 123); + EXPECT_EQ (rc, -1); + + vector_free (small_vector); +} + +TEST_F (VectorTest, Contains) +{ + // No elements + EXPECT_EQ (vector_contains (vector, 1), false); + + // Push one element + vector_push (vector, 1); + EXPECT_EQ (vector_contains (vector, 1), true); + + // Update element + vector_set (vector, 0, 2); + EXPECT_EQ (vector_contains (vector, 1), false); + EXPECT_EQ (vector_contains (vector, 2), true); +} + +TEST_F (VectorTest, Remove) +{ + // Remove element at invalid position + int rc = vector_remove_at (vector, 2); + EXPECT_EQ (rc, -1); // Failure + + // Push two elements and remove the second one + vector_push (vector, 1); + vector_push (vector, 2); + rc = vector_remove_at (vector, 1); + EXPECT_EQ (rc, 0); // Success + EXPECT_EQ (vector_len (vector), size_t (1)); + + // Push another element: it should replace the previous one + vector_push (vector, 3); + EXPECT_EQ (vector_len (vector), size_t (2)); + EXPECT_EQ (vector_at (vector, 1), 3); +} + +TEST_F (VectorTest, RemoveInTheMiddle) +{ + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + + // Remove element in central position + int rc = vector_remove_at (vector, 2); + EXPECT_EQ (rc, 0); // Success + EXPECT_EQ (vector_contains (vector, 2), false); + EXPECT_EQ (vector_len (vector), N_ELEMENTS - 1); + + // Check if elements have been shifted (preserving the order) + int expected[] = { 0, 1, 3, 4 }; + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_EQ (vector_at (vector, i), expected[i]); +} + +TEST_F (VectorTest, Reset) +{ + vector_push (vector, 1); + vector_push (vector, 2); + EXPECT_EQ (vector_len (vector), size_t (2)); + + vector_reset (vector); + EXPECT_EQ (vector_len (vector), size_t (0)); + + vector_push (vector, 5); + EXPECT_EQ (vector_len (vector), size_t (1)); + EXPECT_EQ (vector_contains (vector, 5), true); + EXPECT_EQ (vector_at (vector, 0), 5); +}
\ No newline at end of file diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c index 412baddcf..ba7c6475b 100644 --- a/lib/src/util/ip_address.c +++ b/lib/src/util/ip_address.c @@ -21,6 +21,7 @@ #include <hicn/util/ip_address.h> #include <hicn/util/log.h> #include <hicn/util/sstrncpy.h> +#include <hicn/common.h> #if __BYTE_ORDER == __LITTLE_ENDIAN #ifdef __ANDROID__ @@ -33,38 +34,44 @@ #endif /* No htonl() with const */ -const ip_address_t IPV4_LOOPBACK = { +const hicn_ip_address_t IPV4_LOOPBACK = { .v4.as_inaddr.s_addr = SWAP (INADDR_LOOPBACK), }; -const ip_address_t IPV6_LOOPBACK = { +const hicn_ip_address_t IPV6_LOOPBACK = { .v6.as_in6addr = IN6ADDR_LOOPBACK_INIT, }; -const ip_address_t IPV4_ANY = { +const hicn_ip_address_t IPV4_ANY = { .v4.as_inaddr.s_addr = INADDR_ANY, }; -const ip_address_t IPV6_ANY = { +const hicn_ip_address_t IPV6_ANY = { .v6.as_in6addr = IN6ADDR_ANY_INIT, }; -const ip4_address_t IP4_ADDRESS_EMPTY = { +const ipv4_address_t IP4_ADDRESS_EMPTY = { .as_u32 = 0, }; -const ip6_address_t IP6_ADDRESS_EMPTY = { +const ipv6_address_t IP6_ADDRESS_EMPTY = { .as_u64 = { 0, 0 }, }; -const ip_address_t IP_ADDRESS_EMPTY = { +const hicn_ip_address_t IP_ADDRESS_EMPTY = { .v6.as_u64 = { 0, 0 }, }; /* IP address */ int -ip_address_get_family (const char *ip_address) +hicn_ip_address_get_family (const hicn_ip_address_t *address) +{ + return hicn_ip_address_is_v4 (address) ? AF_INET : AF_INET6; +} + +int +hicn_ip_address_str_get_family (const char *ip_address) { struct addrinfo hint, *res = NULL; int rc; @@ -85,7 +92,7 @@ ip_address_get_family (const char *ip_address) } int -ip_address_len (int family) +hicn_ip_address_len (int family) { return (family == AF_INET6) ? IPV6_ADDR_LEN : (family == AF_INET) ? IPV4_ADDR_LEN : @@ -93,8 +100,20 @@ ip_address_len (int family) } int -ip_address_ntop (const ip_address_t *ip_address, char *dst, const size_t len, - int family) +hicn_ip_address_get_len (const hicn_ip_address_t *ip_address) +{ + return hicn_ip_address_len (hicn_ip_address_get_family (ip_address)); +} + +int +hicn_ip_address_get_len_bits (const hicn_ip_address_t *ip_address) +{ + return bytes_to_bits (hicn_ip_address_get_len (ip_address)); +} + +int +hicn_ip_address_ntop (const hicn_ip_address_t *ip_address, char *dst, + const size_t len, int family) { const char *s; switch (family) @@ -115,12 +134,13 @@ ip_address_ntop (const ip_address_t *ip_address, char *dst, const size_t len, * Parse ip addresses in presentation format */ int -ip_address_pton (const char *ip_address_str, ip_address_t *ip_address) +hicn_ip_address_pton (const char *hicn_ip_address_str, + hicn_ip_address_t *ip_address) { int pton_fd; int family; - family = ip_address_get_family (ip_address_str); + family = hicn_ip_address_str_get_family (hicn_ip_address_str); switch (family) { @@ -128,10 +148,12 @@ ip_address_pton (const char *ip_address_str, ip_address_t *ip_address) ip_address->pad[0] = 0; ip_address->pad[1] = 0; ip_address->pad[2] = 0; - pton_fd = inet_pton (AF_INET, ip_address_str, &ip_address->v4.buffer); + pton_fd = + inet_pton (AF_INET, hicn_ip_address_str, &ip_address->v4.buffer); break; case AF_INET6: - pton_fd = inet_pton (AF_INET6, ip_address_str, &ip_address->v6.buffer); + pton_fd = + inet_pton (AF_INET6, hicn_ip_address_str, &ip_address->v6.buffer); break; default: return -1; @@ -146,11 +168,11 @@ ip_address_pton (const char *ip_address_str, ip_address_t *ip_address) } int -ip_address_snprintf (char *s, size_t size, const ip_address_t *ip_address, - int family) +hicn_ip_address_snprintf (char *s, size_t size, + const hicn_ip_address_t *ip_address) { - const char *rc; + int family = hicn_ip_address_get_family (ip_address); switch (family) { case AF_INET: @@ -172,8 +194,8 @@ ip_address_snprintf (char *s, size_t size, const ip_address_t *ip_address, } int -ip_address_to_sockaddr (const ip_address_t *ip_address, struct sockaddr *sa, - int family) +hicn_ip_address_to_sockaddr (const hicn_ip_address_t *ip_address, + struct sockaddr *sa, int family) { struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *) sa; struct sockaddr_in *tmp4 = (struct sockaddr_in *) sa; @@ -199,64 +221,66 @@ ip_address_to_sockaddr (const ip_address_t *ip_address, struct sockaddr *sa, } int -ip_address_cmp (const ip_address_t *ip1, const ip_address_t *ip2, int family) +hicn_ip_address_cmp (const hicn_ip_address_t *ip1, + const hicn_ip_address_t *ip2) { - switch (family) - { - case AF_INET: - return memcmp (ip1->v4.buffer, ip2->v4.buffer, sizeof (ip1->v4)); - case AF_INET6: - default: - return memcmp (ip1->v6.buffer, ip2->v6.buffer, sizeof (ip1->v6)); - } + /* This works as soon as all members are initialized */ + return memcmp (ip1, ip2, sizeof (hicn_ip_address_t)); +} + +bool +hicn_ip_address_equals (const hicn_ip_address_t *ip1, + const hicn_ip_address_t *ip2) +{ + return hicn_ip_address_cmp (ip1, ip2) == 0; } int -ip_address_empty (const ip_address_t *ip) +hicn_ip_address_empty (const hicn_ip_address_t *ip) { - return (memcmp (ip->v6.buffer, &IP_ADDRESS_EMPTY.v6.buffer, - sizeof (IP_ADDRESS_EMPTY)) == 0); + return (memcmp (ip, &IP_ADDRESS_EMPTY, sizeof (hicn_ip_address_t)) == 0); } /* Prefix */ /* Parse IP Prefixes in presentation format (in bits, separated by a slash) */ int -ip_prefix_pton (const char *ip_address_str, ip_prefix_t *ip_prefix) +hicn_ip_prefix_pton (const char *hicn_ip_address_str, + hicn_ip_prefix_t *hicn_ip_prefix) { int pton_fd; char *p; char *eptr; - char *addr = strdup (ip_address_str); + char *addr = strdup (hicn_ip_address_str); p = strchr (addr, '/'); if (!p) { - ip_prefix->len = ~0; // until we get the ip address family + hicn_ip_prefix->len = ~0; // until we get the ip address family } else { - ip_prefix->len = (u8) strtoul (p + 1, &eptr, 10); + hicn_ip_prefix->len = (u8) strtoul (p + 1, &eptr, 10); *p = 0; } - ip_prefix->family = ip_address_get_family (addr); + hicn_ip_prefix->family = hicn_ip_address_str_get_family (addr); - switch (ip_prefix->family) + switch (hicn_ip_prefix->family) { case AF_INET6: - if (ip_prefix->len == (u8) ~0) - ip_prefix->len = IPV6_ADDR_LEN_BITS; - if (ip_prefix->len > IPV6_ADDR_LEN_BITS) + if (hicn_ip_prefix->len == (u8) ~0) + hicn_ip_prefix->len = IPV6_ADDR_LEN_BITS; + if (hicn_ip_prefix->len > IPV6_ADDR_LEN_BITS) goto ERR; - pton_fd = inet_pton (AF_INET6, addr, &ip_prefix->address.v6.buffer); + pton_fd = inet_pton (AF_INET6, addr, &hicn_ip_prefix->address.v6.buffer); break; case AF_INET: - if (ip_prefix->len == (u8) ~0) - ip_prefix->len = IPV4_ADDR_LEN_BITS; - if (ip_prefix->len > IPV4_ADDR_LEN_BITS) + if (hicn_ip_prefix->len == (u8) ~0) + hicn_ip_prefix->len = IPV4_ADDR_LEN_BITS; + if (hicn_ip_prefix->len > IPV4_ADDR_LEN_BITS) goto ERR; - pton_fd = inet_pton (AF_INET, addr, &ip_prefix->address.v4.buffer); + pton_fd = inet_pton (AF_INET, addr, &hicn_ip_prefix->address.v4.buffer); break; default: goto ERR; @@ -275,18 +299,19 @@ ERR: } int -ip_prefix_ntop_short (const ip_prefix_t *ip_prefix, char *dst, size_t size) +hicn_ip_prefix_ntop_short (const hicn_ip_prefix_t *hicn_ip_prefix, char *dst, + size_t size) { char ip_s[MAXSZ_IP_ADDRESS]; const char *s; - switch (ip_prefix->family) + switch (hicn_ip_prefix->family) { case AF_INET: - s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s, + s = inet_ntop (AF_INET, hicn_ip_prefix->address.v4.buffer, ip_s, MAXSZ_IP_ADDRESS); break; case AF_INET6: - s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s, + s = inet_ntop (AF_INET6, hicn_ip_prefix->address.v6.buffer, ip_s, MAXSZ_IP_ADDRESS); break; default: @@ -301,18 +326,19 @@ ip_prefix_ntop_short (const ip_prefix_t *ip_prefix, char *dst, size_t size) } int -ip_prefix_ntop (const ip_prefix_t *ip_prefix, char *dst, size_t size) +hicn_ip_prefix_ntop (const hicn_ip_prefix_t *hicn_ip_prefix, char *dst, + size_t size) { char ip_s[MAXSZ_IP_ADDRESS]; const char *s; - switch (ip_prefix->family) + switch (hicn_ip_prefix->family) { case AF_INET: - s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s, + s = inet_ntop (AF_INET, hicn_ip_prefix->address.v4.buffer, ip_s, MAXSZ_IP_ADDRESS); break; case AF_INET6: - s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s, + s = inet_ntop (AF_INET6, hicn_ip_prefix->address.v6.buffer, ip_s, MAXSZ_IP_ADDRESS); break; default: @@ -320,26 +346,26 @@ ip_prefix_ntop (const ip_prefix_t *ip_prefix, char *dst, size_t size) } if (!s) return -1; - int rc = snprintf (dst, size, "%s/%d", ip_s, ip_prefix->len); + int rc = snprintf (dst, size, "%s/%d", ip_s, hicn_ip_prefix->len); if (rc >= size) return (int) size; return rc; } int -ip_prefix_snprintf (char *s, size_t size, const ip_prefix_t *prefix) +hicn_ip_prefix_snprintf (char *s, size_t size, const hicn_ip_prefix_t *prefix) { - return ip_prefix_ntop (prefix, s, size); + return hicn_ip_prefix_ntop (prefix, s, size); } int -ip_prefix_len (const ip_prefix_t *prefix) +hicn_ip_prefix_len (const hicn_ip_prefix_t *prefix) { - return prefix->len; // ip_address_len(&prefix->address, prefix->family); + return prefix->len; // hicn_ip_address_len(&prefix->address, prefix->family); } const u8 * -ip_address_get_buffer (const ip_address_t *ip_address, int family) +hicn_ip_address_get_buffer (const hicn_ip_address_t *ip_address, int family) { switch (family) { @@ -353,20 +379,22 @@ ip_address_get_buffer (const ip_address_t *ip_address, int family) } bool -ip_prefix_empty (const ip_prefix_t *prefix) +hicn_ip_prefix_empty (const hicn_ip_prefix_t *prefix) { return prefix->len == 0; } int -ip_prefix_to_sockaddr (const ip_prefix_t *prefix, struct sockaddr *sa) +hicn_ip_prefix_to_sockaddr (const hicn_ip_prefix_t *prefix, + struct sockaddr *sa) { - // XXX assert len == ip_address_len - return ip_address_to_sockaddr (&prefix->address, sa, prefix->family); + // XXX assert len == hicn_ip_address_len + return hicn_ip_address_to_sockaddr (&prefix->address, sa, prefix->family); } int -ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2) +hicn_ip_prefix_cmp (const hicn_ip_prefix_t *prefix1, + const hicn_ip_prefix_t *prefix2) { if (prefix1->family < prefix2->family) return -1; @@ -378,8 +406,26 @@ ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2) else if (prefix1->len > prefix2->len) return 1; - return ip_address_cmp (&prefix1->address, &prefix2->address, - prefix1->family); + return hicn_ip_address_cmp (&prefix1->address, &prefix2->address); +} + +uint8_t +hicn_ip_address_get_bit (const hicn_ip_address_t *address, uint8_t pos) +{ + u64 quad = address->v6.as_u64[pos / 64]; + return quad & (0x1 << pos % 64); +} + +bool +hicn_ip_address_match_family (const hicn_ip_address_t *address, int family) +{ + return hicn_ip_address_get_family (address) == family; +} + +uint32_t +hicn_ip_address_get_hash (const hicn_ip_address_t *address) +{ + return hash32 (address, sizeof (address)); } /* URL */ @@ -395,23 +441,27 @@ ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2) #define MAXSZ_URL MAXSZ_URL_ + NULLTERM int -url_snprintf (char *s, size_t size, int family, const ip_address_t *ip_address, +url_snprintf (char *s, size_t size, const hicn_ip_address_t *ip_address, u16 port) { - char ip_address_s[MAXSZ_IP_ADDRESS]; + char hicn_ip_address_s[MAXSZ_IP_ADDRESS]; int rc; + int family = hicn_ip_address_get_family (ip_address); + /* Other address are currently not supported */ if (!IS_VALID_FAMILY (family)) return -1; + if (!hicn_ip_address_match_family (ip_address, family)) + return -1; rc = - ip_address_snprintf (ip_address_s, MAXSZ_IP_ADDRESS, ip_address, family); + hicn_ip_address_snprintf (hicn_ip_address_s, MAXSZ_IP_ADDRESS, ip_address); if (rc >= MAXSZ_IP_ADDRESS) WARN ("[url_snprintf] Unexpected ip_address truncation"); if (rc < 0) return rc; return snprintf (s, size, "inet%c://%s:%d", (family == AF_INET) ? '4' : '6', - ip_address_s, port); + hicn_ip_address_s, port); } diff --git a/lib/src/util/pool.c b/lib/src/util/pool.c index c6be92ce8..2c1e90b5e 100644 --- a/lib/src/util/pool.c +++ b/lib/src/util/pool.c @@ -28,6 +28,7 @@ #include <stdlib.h> // calloc #include <hicn/util/pool.h> +#include <hicn/util/log.h> #include <stdio.h> // XXX diff --git a/lib/src/util/types.c b/lib/src/util/types.c new file mode 100644 index 000000000..744192593 --- /dev/null +++ b/lib/src/util/types.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <hicn/util/types.h> + +uint32_t +htonf (float f) +{ + uint32_t i; + uint32_t sign = 0; + + if (f < 0) + { + sign = 1; + f = -f; + } + + // i[31] = sign bit + i = sign << 31; + + // i[30 to 16] = int(f)[14 to 0] + i |= (((uint32_t) f) & 0x7fff) << 16; + + // i[15 to 0] = fraction(f) bits [15 to 0] + i |= (uint32_t) ((f - (uint32_t) f) * 65536.0f) & 0xffff; + + return i; +} + +float +ntohf (uint32_t i) +{ + // integer part = i[14 to 0] + float f = (i >> 16) & 0x7fff; + + // fraction part = i[15 to 0] + f += (i & 0xffff) / 65536.0f; + + // sign = i[31] + if ((i >> 31) & 1) + f = -f; + + return f; +} |