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/src/protocol | |
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/src/protocol')
-rw-r--r-- | lib/src/protocol/ah.c | 204 | ||||
-rw-r--r-- | lib/src/protocol/ah.h | 83 | ||||
-rw-r--r-- | lib/src/protocol/icmp.c | 177 | ||||
-rw-r--r-- | lib/src/protocol/icmp.h | 84 | ||||
-rw-r--r-- | lib/src/protocol/icmprd.h | 72 | ||||
-rw-r--r-- | lib/src/protocol/ipv4.c | 496 | ||||
-rw-r--r-- | lib/src/protocol/ipv4.h | 112 | ||||
-rw-r--r-- | lib/src/protocol/ipv6.c | 450 | ||||
-rw-r--r-- | lib/src/protocol/ipv6.h | 86 | ||||
-rw-r--r-- | lib/src/protocol/new.c | 475 | ||||
-rw-r--r-- | lib/src/protocol/new.h | 95 | ||||
-rw-r--r-- | lib/src/protocol/tcp.c | 457 | ||||
-rw-r--r-- | lib/src/protocol/tcp.h | 165 | ||||
-rw-r--r-- | lib/src/protocol/udp.c | 283 | ||||
-rw-r--r-- | lib/src/protocol/udp.h | 44 |
15 files changed, 2180 insertions, 1103 deletions
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: + */ |