diff options
Diffstat (limited to 'lib/src/compat.c')
-rwxr-xr-x | lib/src/compat.c | 1177 |
1 files changed, 1177 insertions, 0 deletions
diff --git a/lib/src/compat.c b/lib/src/compat.c new file mode 100755 index 000000000..7d9eef025 --- /dev/null +++ b/lib/src/compat.c @@ -0,0 +1,1177 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file compat.c + * @brief Implementation of the compatibility layer. + */ + +#include <netinet/in.h> +#include <string.h> // memset +#include <stddef.h> // offsetof + +#include "common.h" +#include "compat.h" +#include "error.h" +#include "header.h" +#include "name.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 + +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_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_ICMPV6: + *format = HF_INET6_ICMP; + break; + default: + return HICN_LIB_ERROR_NOT_HICN; + } + 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_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_NONE,.l2 = IPPROTO_TCP,.l1 = + IPPROTO_IP}; + case HF_INET6_TCP: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_NONE,.l2 = IPPROTO_TCP,.l1 = + IPPROTO_IPV6}; + case HF_INET_ICMP: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_NONE,.l2 = IPPROTO_ICMP,.l1 = + IPPROTO_IP}; + case HF_INET6_ICMP: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_NONE,.l2 = IPPROTO_ICMPV6,.l1 = + IPPROTO_IPV6}; + case HF_INET_TCP_AH: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_AH,.l2 = IPPROTO_TCP,.l1 = IPPROTO_IP}; + case HF_INET6_TCP_AH: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_AH,.l2 = IPPROTO_TCP,.l1 = + IPPROTO_IPV6}; + case HF_INET_ICMP_AH: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_AH,.l2 = IPPROTO_ICMP,.l1 = + IPPROTO_IP}; + case HF_INET6_ICMP_AH: + return (hicn_type_t) + { + .l4 = IPPROTO_NONE,.l3 = IPPROTO_AH,.l2 = IPPROTO_ICMPV6,.l1 = + IPPROTO_IPV6}; + default: + break; + } + return (hicn_type_t) + { + { + IPPROTO_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); + 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 (hicn_format_t format, hicn_header_t * h) +{ + hicn_type_t type = hicn_format_to_type (format); + return hicn_ops_vft[type.l1]->verify_checksums (type, &h->protocol, 0, 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_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_packet_get_header_length_from_format (format, header_length); + int is_ah = _is_ah (format); + int is_ipv4 = _is_ipv4 (format); + int is_ipv6 = _is_ipv6 (format); + // The signature payload is expressed as number of 32 bits words + *header_length += (is_ah * is_ipv4) * (h->v4ah.ah.payloadlen) << 2; + *header_length += (is_ah * is_ipv6) * (h->v6ah.ah.payloadlen) << 2; + + return HICN_LIB_ERROR_NONE; +} + +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, + 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); + +#ifndef HICN_VPP_PLUGIN + if (name->type & HNT_IOV) + return HICN_LIB_ERROR_NOT_IMPLEMENTED; +#endif /* HICN_VPP_PLUGIN */ + + 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 * ip_address, bool is_interest) +{ + const void *locator; + int is_ipv4 = (format & HFO_INET); + int is_ipv6 = (format & HFO_INET6) >> 1; + + if (is_ipv4) + { + locator = is_interest ? &h->v4.ip.saddr : &h->v4.ip.daddr; + ip_address->family = AF_INET; + ip_address->prefix_len = IPV4_ADDR_LEN_BITS; + } + else if (is_ipv6) + { + locator = is_interest ? &h->v6.ip.saddr : &h->v6.ip.daddr; + ip_address->family = AF_INET6; + ip_address->prefix_len = IPV6_ADDR_LEN_BITS; + } + else + { + return HICN_LIB_ERROR_NOT_IMPLEMENTED; + } + + memcpy (ip_address->buffer, locator, ip_address_len (ip_address)); + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_locator (hicn_format_t format, hicn_header_t * h, + const ip_address_t * ip_address, bool is_interest) +{ + void *locator; + int is_ipv4 = (format & HFO_INET); + int is_ipv6 = (format & HFO_INET6) >> 1; + + if (is_ipv6) + { + locator = is_interest ? &h->v6.ip.saddr : &h->v6.ip.daddr; + } + else if (is_ipv4) + { + locator = is_interest ? &h->v4.ip.saddr : &h->v4.ip.daddr; + } + else + { + return HICN_LIB_ERROR_INVALID_PARAMETER; + } + + memcpy (locator, ip_address->buffer, ip_address_len (ip_address)); + + return HICN_LIB_ERROR_NONE; +} + +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_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_get_lifetime (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_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 = h->v6.tcp.reserved; + break; + case 4: + *reserved_bits = 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, 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 (const hicn_header_t * h, + hicn_payload_type_t * payload_type) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + *payload_type = ((h->v6.tcp.flags & TCP_FLAG_URG) == TCP_FLAG_URG); + break; + case 4: + *payload_type = ((h->v4.tcp.flags & TCP_FLAG_URG) == TCP_FLAG_URG); + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + + if (*payload_type == HPT_UNSPEC) + { + return HICN_LIB_ERROR_UNEXPECTED; + } + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_payload_type (hicn_header_t * h, + hicn_payload_type_t payload_type) +{ + if (payload_type != HPT_DATA && payload_type != HPT_MANIFEST) + { + return HICN_LIB_ERROR_UNEXPECTED; + } + + switch (HICN_IP_VERSION (h)) + { + case 6: + if (payload_type) + h->v6.tcp.flags = h->v6.tcp.flags | TCP_FLAG_URG; + else + h->v6.tcp.flags = h->v6.tcp.flags & ~TCP_FLAG_URG; + break; + case 4: + if (payload_type) + h->v4.tcp.flags = h->v4.tcp.flags | TCP_FLAG_URG; + else + h->v4.tcp.flags = h->v4.tcp.flags & ~TCP_FLAG_URG; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_syn (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags | TCP_FLAG_SYN; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags | TCP_FLAG_SYN; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_reset_syn (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags & ~TCP_FLAG_SYN; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags & ~TCP_FLAG_SYN; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_test_syn (const hicn_header_t * h, bool * flag) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + *flag = h->v6.tcp.flags & TCP_FLAG_SYN; + break; + case 4: + *flag = h->v4.tcp.flags & TCP_FLAG_SYN; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_ack (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags | TCP_FLAG_ACK; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags | TCP_FLAG_ACK; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_reset_ack (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags & ~TCP_FLAG_ACK; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags & ~TCP_FLAG_ACK; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_test_ack (const hicn_header_t * h, bool * flag) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + *flag = h->v6.tcp.flags & TCP_FLAG_ACK; + break; + case 4: + *flag = h->v4.tcp.flags & TCP_FLAG_ACK; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_rst (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags | TCP_FLAG_RST; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags | TCP_FLAG_RST; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_reset_rst (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags & ~TCP_FLAG_RST; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags & ~TCP_FLAG_RST; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_test_rst (const hicn_header_t * h, bool * flag) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + *flag = h->v6.tcp.flags & TCP_FLAG_RST; + break; + case 4: + *flag = h->v4.tcp.flags & TCP_FLAG_RST; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_fin (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags | TCP_FLAG_FIN; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags | TCP_FLAG_FIN; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_reset_fin (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags & ~TCP_FLAG_FIN; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags & ~TCP_FLAG_FIN; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_test_fin (const hicn_header_t * h, bool * flag) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + *flag = h->v6.tcp.flags & TCP_FLAG_FIN; + break; + case 4: + *flag = h->v4.tcp.flags & TCP_FLAG_FIN; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_ece (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags | TCP_FLAG_ECE; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags | TCP_FLAG_ECE; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_reset_ece (hicn_header_t * h) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + h->v6.tcp.flags = h->v6.tcp.flags & ~TCP_FLAG_ECE; + break; + case 4: + h->v4.tcp.flags = h->v4.tcp.flags & ~TCP_FLAG_ECE; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_test_ece (const hicn_header_t * h, bool * flag) +{ + switch (HICN_IP_VERSION (h)) + { + case 6: + *flag = h->v6.tcp.flags & TCP_FLAG_ECE; + break; + case 4: + *flag = h->v4.tcp.flags & TCP_FLAG_ECE; + break; + default: + return HICN_LIB_ERROR_UNEXPECTED; + } + return HICN_LIB_ERROR_NONE; +} + +int +hicn_packet_set_src_port (hicn_header_t * h, u16 src_port) +{ + 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 (const hicn_header_t * h, u16 * src_port) +{ + 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_header_t * h, u16 dst_port) +{ + 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 (const hicn_header_t * h, u16 * dst_port) +{ + 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) +{ + int ret_err = hicn_packet_reset_ece (interest); //interest packet -> ece flag unset + if (ret_err < 0) + return HICN_LIB_ERROR_UNEXPECTED; + 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 * ip_address) +{ + return hicn_packet_get_locator (format, interest, ip_address, _INTEREST); +} + +int +hicn_interest_set_locator (hicn_format_t format, hicn_header_t * interest, + const ip_address_t * ip_address) +{ + return hicn_packet_set_locator (format, interest, ip_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) +{ + return hicn_packet_get_lifetime (interest, lifetime); +} + +int +hicn_interest_set_lifetime (hicn_header_t * interest, u32 lifetime) +{ + return hicn_packet_set_lifetime (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, 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, + hicn_name_t * name) +{ + int ret_err = hicn_packet_set_ece (data); //data packet -> ece flag set + if (ret_err < 0) + return HICN_LIB_ERROR_UNEXPECTED; + 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 * ip_address) +{ + return hicn_packet_get_locator (format, data, ip_address, _DATA); +} + +int +hicn_data_set_locator (hicn_format_t format, hicn_header_t * data, + const ip_address_t * ip_address) +{ + return hicn_packet_set_locator (format, data, ip_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) +{ + return hicn_packet_get_lifetime (data, expiry_time); +} + +int +hicn_data_set_expiry_time (hicn_header_t * data, u32 expiry_time) +{ + return hicn_packet_set_lifetime (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_set_payload_type (hicn_header_t * data, + hicn_payload_type_t payload_type) +{ + return hicn_packet_set_payload_type (data, payload_type); +} + +int +hicn_data_get_payload_type (const hicn_header_t * data, + hicn_payload_type_t * payload_type) +{ + return hicn_packet_get_payload_type (data, payload_type); +} + +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, 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_interest_for_hash (type, + &packet->protocol); + +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |