aboutsummaryrefslogtreecommitdiffstats
path: root/lib/src/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src/protocol')
-rwxr-xr-xlib/src/protocol/ah.c211
-rwxr-xr-xlib/src/protocol/ah.h72
-rwxr-xr-xlib/src/protocol/icmp.c229
-rwxr-xr-xlib/src/protocol/icmp.h68
-rwxr-xr-xlib/src/protocol/icmprd.h47
-rwxr-xr-xlib/src/protocol/ipv4.c452
-rwxr-xr-xlib/src/protocol/ipv4.h91
-rwxr-xr-xlib/src/protocol/ipv6.c412
-rwxr-xr-xlib/src/protocol/ipv6.h67
-rwxr-xr-xlib/src/protocol/tcp.c370
-rwxr-xr-xlib/src/protocol/tcp.h166
-rwxr-xr-xlib/src/protocol/udp.h37
12 files changed, 2222 insertions, 0 deletions
diff --git a/lib/src/protocol/ah.c b/lib/src/protocol/ah.c
new file mode 100755
index 000000000..f9ddf7775
--- /dev/null
+++ b/lib/src/protocol/ah.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file protocol/ah.c
+ * @brief hICN operations for AH header
+ */
+
+#include <string.h> // memcpy
+#include "../common.h"
+#include "../error.h"
+#include "../header.h"
+#include "../ops.h"
+#include "ah.h"
+
+DECLARE_get_interest_locator (ah, UNEXPECTED);
+DECLARE_set_interest_locator (ah, UNEXPECTED);
+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_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_lifetime (ah, UNEXPECTED);
+DECLARE_set_lifetime (ah, UNEXPECTED);
+DECLARE_get_payload_length (ah, UNEXPECTED);
+DECLARE_set_payload_length (ah, UNEXPECTED);
+
+int
+ah_init_packet_header (hicn_type_t type, hicn_protocol_t * h)
+{
+ return HICN_LIB_ERROR_NOT_IMPLEMENTED;
+}
+
+int
+ah_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ size_t signature_size;
+ int rc =
+ hicn_ops_vft[type.l1]->get_signature_size (type, h, &signature_size);
+ if (rc < 0)
+ return rc;
+ memset (&(h->ah.validationPayload), 0, signature_size);
+ return CHILD_OPS (reset_interest_for_hash, type, h);
+}
+
+int
+ah_reset_data_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ size_t signature_size;
+ int rc =
+ hicn_ops_vft[type.l1]->get_signature_size (type, h, &signature_size);
+ if (rc < 0)
+ return rc;
+ memset (&(h->ah.validationPayload), 0, signature_size);
+ return CHILD_OPS (reset_interest_for_hash, type, h);
+}
+
+int
+ah_update_checksums (hicn_type_t type, hicn_protocol_t * h, u16 partial_csum,
+ size_t payload_length)
+{
+ /* 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)
+{
+ /* Nothing to do as there is no checksum in AH */
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new,
+ ip46_address_t * addr_old)
+{
+ /* Nothing to do on signature */
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new, ip46_address_t * addr_old,
+ const hicn_faceid_t face_id)
+{
+ /* 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)
+{
+ *header_length = AH_HDRLEN + (h->ah.payloadlen << 2);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_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 = AH_HDRLEN + (h->ah.payloadlen << 2) + child_header_length;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_get_signature_size (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * signature_size)
+{
+ *signature_size = h->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)
+{
+ h->ah.payloadlen = signature_size >> 2;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_set_signature_timestamp(hicn_type_t type, hicn_protocol_t * h,
+ uint64_t signature_timestamp)
+{
+ h->ah.timestamp_as_u64 = signature_timestamp;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t * h,
+ uint64_t * signature_timestamp)
+{
+ *signature_timestamp = h->ah.timestamp_as_u64;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_set_validation_algorithm (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t validation_algorithm)
+{
+ h->ah.validationAlgorithm = validation_algorithm;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t * h,
+ uint8_t * validation_algorithm)
+{
+ *validation_algorithm = h->ah.validationAlgorithm;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_set_key_id (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t *key_id)
+{
+ memcpy(h->ah.keyId, key_id, sizeof(h->ah.keyId));
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ah_get_key_id (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t **key_id, uint8_t *key_id_size)
+{
+ *key_id = h->ah.keyId;
+ *key_id_size = sizeof(h->ah.keyId);
+ return HICN_LIB_ERROR_NONE;
+}
+
+DECLARE_HICN_OPS (ah);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/ah.h b/lib/src/protocol/ah.h
new file mode 100755
index 000000000..0b4171135
--- /dev/null
+++ b/lib/src/protocol/ah.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file protocol/ah.h
+ * @brief AH packet header
+ */
+#ifndef HICN_PROTOCOL_AH_H
+#define HICN_PROTOCOL_AH_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
+
+typedef struct
+{
+ u8 nh; // (to match with reserved in IPSEC AH)
+ u8 payloadlen; // Len of signature/HMAC in 4-bytes words
+ union
+ {
+ u16 reserved;
+ struct
+ {
+ u8 validationAlgorithm; // As defined in parc_SignerAlgorithm.h
+ u8 unused; // Unused (to match with reserved in IPSEC AH)
+ };
+ };
+ union
+ {
+ struct
+ {
+ u32 spi;
+ u32 seq;
+ };
+ union
+ {
+ u8 timestamp_as_u8[8];
+ u64 timestamp_as_u64;
+ }; // Unix timestamp indicating when the signature has been calculated
+
+ };
+ // ICV would follow
+ u8 keyId[32]; // Hash of the pub key
+ /* 44 B + validationPayload */
+ u8 validationPayload[0]; // Holds the signature
+} _ah_header_t;
+
+#define AH_HDRLEN sizeof(_ah_header_t)
+
+#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
new file mode 100755
index 000000000..44b646fb2
--- /dev/null
+++ b/lib/src/protocol/icmp.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "icmp.h"
+
+#include "../error.h"
+#include "../ops.h"
+
+DECLARE_get_interest_locator (icmp, UNEXPECTED)
+DECLARE_set_interest_locator (icmp, UNEXPECTED)
+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_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_lifetime (icmp, UNEXPECTED)
+DECLARE_set_lifetime (icmp, UNEXPECTED)
+DECLARE_get_length (icmp, UNEXPECTED)
+DECLARE_get_payload_length (icmp, UNEXPECTED)
+DECLARE_set_payload_length (icmp, UNEXPECTED)
+ int icmp_init_packet_header (hicn_type_t type, hicn_protocol_t * h)
+{
+ h->icmp = (_icmp_header_t)
+ {
+ .type = 0,.code = 0,.csum = 0,};
+
+ return HICN_LIB_ERROR_NONE; // CHILD_OPS(init_packet_header, type, h->icmp);
+}
+
+int
+icmp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ h->icmp.csum = 0;
+
+ return CHILD_OPS (reset_interest_for_hash, type, h);
+}
+
+int
+icmp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ h->icmp.csum = 0;
+
+ return CHILD_OPS (reset_data_for_hash, type, h);
+}
+
+int
+icmp_update_checksums (hicn_type_t type, hicn_protocol_t * h,
+ u16 partial_csum, size_t payload_length)
+{
+ return HICN_LIB_ERROR_NOT_IMPLEMENTED;
+// h->icmp.csum = 0;
+// h->icmp.csum = csum(h->bytes, TCP_HDRLEN + payload_length, ~partial_csum);
+//
+// return CHILD_OPS(update_checksums, type, h->icmp, 0, payload_length);
+}
+
+int
+icmp_verify_checksums (hicn_type_t type, hicn_protocol_t * h,
+ u16 partial_csum, size_t payload_length)
+{
+ return HICN_LIB_ERROR_NOT_IMPLEMENTED;
+// if (csum(h->bytes, TCP_HDRLEN + payload_length, ~partial_csum) != 0)
+// return HICN_LIB_ERROR_CORRUPTED_PACKET;
+// return CHILD_OPS(verify_checksums, type, h->icmp, 0, payload_length);
+}
+
+int
+icmp_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new,
+ ip46_address_t * addr_old)
+{
+ return HICN_LIB_ERROR_NOT_IMPLEMENTED;
+// u16 *icmp_checksum = &(h->icmp.csum);
+//
+// /*
+// * Padding fields are set to zero so we can apply checksum on the
+// * whole struct by interpreting it as IPv6 in all cases
+// *
+// * v4 code would be:
+// * csum = ip_csum_sub_even (*icmp_checksum, h->ipv4.saddr.as_u32);
+// * csum = ip_csum_add_even (csum, h->ipv4.saddr.as_u32);
+// */
+// u16 csum = ip_csum_sub_even (*icmp_checksum, h->ipv6.saddr.as_u64[0]);
+// csum = ip_csum_sub_even (csum, h->ipv6.saddr.as_u64[1]);
+// csum = ip_csum_add_even (csum, h->ipv6.saddr.as_u64[0]);
+// csum = ip_csum_add_even (csum, h->ipv6.saddr.as_u64[1]);
+//
+// *icmp_checksum = ip_csum_fold (csum);
+//
+// return HICN_LIB_ERROR_NONE;
+}
+
+int
+icmp_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new, ip46_address_t * addr_old,
+ const hicn_faceid_t face_id)
+{
+ return HICN_LIB_ERROR_NOT_IMPLEMENTED;
+// u16 *icmp_checksum = &(h->icmp.csum);
+//
+// /*
+// * Padding fields are set to zero so we can apply checksum on the
+// * whole struct by interpreting it as IPv6 in all cases
+// *
+// * v4 code would be:
+// * csum = ip_csum_sub_even (*icmp_checksum, h->ipv4.saddr.as_u32);
+// * csum = ip_csum_add_even (csum, h->ipv4.saddr.as_u32);
+// */
+// u16 csum = ip_csum_sub_even (*icmp_checksum, addr_old->ip6.as_u64[0]);
+// csum = ip_csum_sub_even (*icmp_checksum, addr_old->ip6.as_u64[1]);
+// 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);
+//
+// *icmp_checksum = ip_csum_fold (csum);
+//
+// return HICN_LIB_ERROR_NONE;
+}
+
+int
+icmp_get_current_header_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * header_length)
+{
+ *header_length = ICMP_HDRLEN;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+icmp_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 = ICMP_HDRLEN + child_header_length;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+icmp_get_signature_size (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * signature_size)
+{
+ return CHILD_OPS (get_signature_size, type, h, signature_size);
+}
+
+int
+icmp_set_signature_size (hicn_type_t type, hicn_protocol_t * h,
+ size_t signature_size)
+{
+ return CHILD_OPS (set_signature_size, type, h, signature_size);
+}
+
+int
+icmp_set_signature_timestamp(hicn_type_t type, hicn_protocol_t * h,
+ uint64_t signature_timestamp)
+{
+ return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+icmp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t * h,
+ uint64_t * signature_timestamp)
+{
+ return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+icmp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t validation_algorithm)
+{
+ return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+icmp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t * h,
+ uint8_t * validation_algorithm)
+{
+ return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+icmp_set_key_id (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t *key_id)
+{
+ return CHILD_OPS (set_key_id, type, h, key_id);
+}
+
+int
+icmp_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);
+}
+
+DECLARE_HICN_OPS (icmp);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/icmp.h b/lib/src/protocol/icmp.h
new file mode 100755
index 000000000..5a84995b6
--- /dev/null
+++ b/lib/src/protocol/icmp.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file protocol/icmp.h
+ * @brief ICMP packet header
+ */
+#ifndef HICN_PROTOCOL_ICMP_H
+#define HICN_PROTOCOL_ICMP_H
+
+#include "../common.h"
+
+typedef struct
+{
+ u8 type;
+ u8 code;
+ u16 csum;
+} _icmp_header_t;
+
+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 ICMP_HDRLEN sizeof(_icmp_header_t)
+
+#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 100755
index 000000000..c2f27d673
--- /dev/null
+++ b/lib/src/protocol/icmprd.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file protocol/icmp-rd.c
+ * @brief hICN operations for ICMP Redirect header
+ */
+#ifndef HICN_PROTOCOL_ICMPRD_H
+#define HICN_PROTOCOL_ICMPRD_H
+
+#include "../common.h"
+
+typedef struct __attribute__ ((__packed__))
+{
+ ip4_address_t ip;
+ _ipv4_header_t iph;
+ u8 data[64];
+} _icmprd4_header_t;
+
+typedef struct __attribute__ ((__packed__))
+{
+ u32 res;
+ ip6_address_t tgt;
+ ip6_address_t dst;
+} _icmprd_header_t;
+
+#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
new file mode 100755
index 000000000..7c6af127d
--- /dev/null
+++ b/lib/src/protocol/ipv4.c
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file protocol/ipv4.c
+ * @brief hICN operations for IPv4 header
+ *
+ * NOTE: IPv4 options (affecting the header size) are currently not supported.
+ */
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../error.h"
+#include "../ops.h"
+#include "../common.h"
+#include "../header.h"
+
+#include "ipv4.h"
+
+int ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * payload_length);
+
+int
+ipv4_init_packet_header (hicn_type_t type, hicn_protocol_t * h)
+{
+ 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;
+
+ h->ipv4 = (_ipv4_header_t)
+ {
+ .version_ihl =
+ (IPV4_DEFAULT_VERSION << 4) | (0x0f & IPV4_DEFAULT_IHL),.tos =
+ IPV4_DEFAULT_TOS,.len = htons ((u16) total_header_length),.id =
+ htons (IPV4_DEFAULT_ID),.frag_off =
+ htons (IPV4_DEFAULT_FRAG_OFF),.ttl = HICN_DEFAULT_TTL,.protocol =
+ type.l2,.csum = 0,.saddr.as_u32 = 0,.daddr.as_u32 = 0,};
+
+ return CHILD_OPS (init_packet_header, type, h);
+}
+
+int
+ipv4_get_interest_locator (hicn_type_t type, const hicn_protocol_t * h,
+ ip46_address_t * ip_address)
+{
+ ip_address->ip4 = h->ipv4.saddr;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_set_interest_locator (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * ip_address)
+{
+ h->ipv4.saddr = ip_address->ip4;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_get_interest_name (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_t * name)
+{
+ name->ip4.prefix_as_ip4 = h->ipv4.daddr;
+#ifndef HICN_VPP_PLUGIN
+ name->type = HNT_CONTIGUOUS_V4;
+ name->len = HICN_V4_NAME_LEN;
+#endif /* HICN_VPP_PLUGIN */
+ return CHILD_OPS (get_interest_name_suffix, type, h, &(name->ip4.suffix));
+}
+
+int
+ipv4_set_interest_name (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_t * name)
+{
+ h->ipv4.daddr = name->ip4.prefix_as_ip4;
+ return CHILD_OPS (set_interest_name_suffix, type, h, &(name->ip4.suffix));
+}
+
+int
+ipv4_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (set_interest_name_suffix, type, h, suffix);
+}
+
+int
+ipv4_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (set_interest_name_suffix, type, h, suffix);
+}
+
+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);
+
+ return CHILD_OPS (reset_interest_for_hash, type, h);
+}
+
+int
+ipv4_get_data_locator (hicn_type_t type, const hicn_protocol_t * h,
+ ip46_address_t * ip_address)
+{
+ ip_address->ip4 = h->ipv4.daddr;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_set_data_locator (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * ip_address)
+{
+ h->ipv4.daddr = ip_address->ip4;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_get_data_name (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_t * name)
+{
+ name->ip4.prefix_as_ip4 = h->ipv4.saddr;
+#ifndef HICN_VPP_PLUGIN
+ name->type = HNT_CONTIGUOUS_V4;
+ name->len = HICN_V4_NAME_LEN;
+#endif /* HICN_VPP_PLUGIN */
+ return CHILD_OPS (get_data_name_suffix, type, h, &(name->ip4.suffix));
+}
+
+int
+ipv4_set_data_name (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_t * name)
+{
+ h->ipv4.saddr = name->ip4.prefix_as_ip4;
+ return CHILD_OPS (set_data_name_suffix, type, h, &(name->ip4.suffix));
+}
+
+int
+ipv4_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (get_data_name_suffix, type, h, suffix);
+}
+
+int
+ipv4_set_data_name_suffix (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (set_data_name_suffix, type, h, suffix);
+}
+
+int
+ipv4_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t * h,
+ u32 * pathlabel)
+{
+ return CHILD_OPS (get_data_pathlabel, type, h, pathlabel);
+}
+
+int
+ipv4_set_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
+ const u32 pathlabel)
+{
+ return CHILD_OPS (set_data_pathlabel, type, h, pathlabel);
+}
+
+int
+ipv4_update_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_faceid_t face_id)
+{
+ return CHILD_OPS (update_data_pathlabel, type, h, face_id);
+}
+
+int
+ipv4_reset_data_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ /* Sets everything to 0 up to source address */
+ memset (&h->ipv4, 0, 12);
+ /* Clears destination address */
+ memset (&(h->ipv4.daddr), 0, 4);
+
+ return CHILD_OPS (reset_data_for_hash, type, h);
+}
+
+int
+ipv4_get_lifetime (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_lifetime_t * lifetime)
+{
+ return CHILD_OPS (get_lifetime, type, h, lifetime);
+}
+
+int
+ipv4_set_lifetime (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_lifetime_t lifetime)
+{
+ return CHILD_OPS (set_lifetime, type, h, lifetime);
+}
+
+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);
+
+ /* Retrieve payload length if not specified, as it is not available later */
+ if (payload_length == 0)
+ {
+ int rc = ipv4_get_payload_length (type, h, &payload_length);
+ if (rc < 0)
+ return rc;
+ }
+
+ /* Ignore the payload if payload_length = ~0 */
+ if (payload_length == ~0)
+ {
+ payload_length = 0;
+ }
+
+ /* Build pseudo-header */
+ ipv4_pseudo_header_t psh;
+ psh.ip_src = h->ipv4.saddr;
+ psh.ip_dst = h->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.zero = 0;
+ psh.protocol = (u8) h->ipv4.protocol;
+
+ /* Compute partial checksum based on pseudo-header */
+ if (partial_csum != 0)
+ {
+ partial_csum = ~partial_csum;
+ }
+ partial_csum = csum (&psh, IPV4_PSHDRLEN, partial_csum);
+
+ return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length);
+}
+
+int
+ipv4_verify_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.
+ */
+ if (csum (h, 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)
+ {
+ int rc = ipv4_get_payload_length (type, h, &payload_length);
+ if (rc < 0)
+ return rc;
+ }
+
+ /* Build pseudo-header */
+ ipv4_pseudo_header_t psh;
+ psh.ip_src = h->ipv4.saddr;
+ psh.ip_dst = h->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.zero = 0;
+ psh.protocol = (u8) h->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);
+}
+
+int
+ipv4_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new,
+ ip46_address_t * addr_old)
+{
+ // ASSERT(addr_old == NULL);
+ addr_old->ip4 = h->ipv4.saddr;
+ addr_old->pad[0] = 0;
+ addr_old->pad[1] = 0;
+ addr_old->pad[2] = 0;
+
+ h->ipv4.saddr = addr_new->ip4;
+ h->ipv4.csum = 0;
+ h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0);
+
+ return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old);
+}
+
+int
+ipv4_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new, ip46_address_t * addr_old,
+ const hicn_faceid_t face_id)
+{
+ // ASSERT(addr_old == NULL);
+ addr_old->ip4 = h->ipv4.daddr;
+ addr_old->pad[0] = 0;
+ addr_old->pad[1] = 0;
+ addr_old->pad[2] = 0;
+
+ h->ipv4.daddr = addr_new->ip4;
+ h->ipv4.csum = 0;
+ h->ipv4.csum = csum (&h->ipv4, IPV4_HDRLEN, 0);
+
+ return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id);
+}
+
+int
+ipv4_get_current_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * header_length)
+{
+ *header_length = IPV4_HDRLEN;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_get_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * header_length)
+{
+ *header_length = h->ipv4.len;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_get_current_header_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * header_length)
+{
+ *header_length = IPV4_HDRLEN;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_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 = IPV4_HDRLEN + child_header_length;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_get_payload_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * payload_length)
+{
+ 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;
+}
+
+int
+ipv4_set_payload_length (hicn_type_t type, hicn_protocol_t * h,
+ size_t payload_length)
+{
+ 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 (payload_length + IPV4_HDRLEN + child_header_length);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv4_get_signature_size (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * signature_size)
+{
+ return CHILD_OPS (get_signature_size, type, h, signature_size);
+}
+
+int
+ipv4_set_signature_size (hicn_type_t type, hicn_protocol_t * h,
+ size_t signature_size)
+{
+ return CHILD_OPS (set_signature_size, type, h, signature_size);
+}
+
+int
+ipv4_set_signature_timestamp(hicn_type_t type, hicn_protocol_t * h,
+ uint64_t signature_timestamp)
+{
+ return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+ipv4_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t * h,
+ uint64_t * signature_timestamp)
+{
+ return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+ipv4_set_validation_algorithm (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t validation_algorithm)
+{
+ return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+ipv4_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t * h,
+ uint8_t * validation_algorithm)
+{
+ return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+ipv4_set_key_id (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t *key_id)
+{
+ return CHILD_OPS (set_key_id, type, h, key_id);
+}
+
+int
+ipv4_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);
+}
+
+DECLARE_HICN_OPS (ipv4);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/ipv4.h b/lib/src/protocol/ipv4.h
new file mode 100755
index 000000000..c57485b6c
--- /dev/null
+++ b/lib/src/protocol/ipv4.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HICN_PROTOCOL_IPV4
+#define HICN_PROTOCOL_IPV4
+
+#include "../base.h"
+#include "../common.h"
+#include "../protocol.h"
+
+/* Headers were adapted from linux' definitions in netinet/ip.h */
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ u8 ihl:4;
+ u8 version:4;
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ u8 version:4;
+ u8 ihl:4;
+#else
+#error "Unsupported endianness"
+#endif
+ };
+
+ u8 version_ihl;
+ };
+ u8 tos;
+ u16 len;
+ u16 id;
+ u16 frag_off;
+ u8 ttl;
+ u8 protocol;
+ u16 csum;
+ ip4_address_t saddr;
+ ip4_address_t daddr;
+} _ipv4_header_t;
+
+#define ipv4_header_bytes(ipv4_header) (sizeof(u32) * (ipv4_header->version_ihl & 0xf))
+
+#define IPV4_HDRLEN sizeof(_ipv4_header_t)
+
+typedef struct
+{
+ ip4_address_t ip_src;
+ ip4_address_t ip_dst;
+ u8 zero;
+ u8 protocol;
+ u16 size;
+} ipv4_pseudo_header_t;
+
+#define IPV4_PSHDRLEN sizeof(ipv4_pseudo_header_t)
+
+/* 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
new file mode 100755
index 000000000..41b00ec92
--- /dev/null
+++ b/lib/src/protocol/ipv6.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../common.h"
+#include "../error.h"
+#include "../ops.h"
+
+int
+ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * payload_length);
+
+int
+ipv6_init_packet_header (hicn_type_t type, hicn_protocol_t * h)
+{
+ size_t total_header_length;
+ int rc = CHILD_OPS (get_header_length, type, h, &total_header_length);
+ if (rc < 0)
+ return rc;
+
+ /* *INDENT-OFF* */
+ h->ipv6 = (_ipv6_header_t)
+ {
+ .saddr = {{ 0 }}
+ ,.daddr = {{ 0 }}
+ ,.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,
+ .hlim = HICN_DEFAULT_TTL,
+ };
+ /* *INDENT-ON* */
+ return CHILD_OPS (init_packet_header, type, h);
+}
+
+int
+ipv6_get_interest_locator (hicn_type_t type, const hicn_protocol_t * h,
+ ip46_address_t * ip_address)
+{
+ ip_address->ip6 = h->ipv6.saddr;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_set_interest_locator (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * ip_address)
+{
+ h->ipv6.saddr = ip_address->ip6;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_get_interest_name (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_t * name)
+{
+ name->ip6.prefix_as_ip6 = h->ipv6.daddr;
+#ifndef HICN_VPP_PLUGIN
+ name->type = HNT_CONTIGUOUS_V6;
+ name->len = HICN_V6_NAME_LEN;
+#endif /* HICN_VPP_PLUGIN */
+ return CHILD_OPS (get_interest_name_suffix, type, h, &(name->ip6.suffix));
+}
+
+int
+ipv6_set_interest_name (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_t * name)
+{
+ h->ipv6.daddr = name->ip6.prefix_as_ip6;
+ return CHILD_OPS (set_interest_name_suffix, type, h, &(name->ip6.suffix));
+}
+
+int
+ipv6_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (get_interest_name_suffix, type, h, suffix);
+}
+
+int
+ipv6_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (set_interest_name_suffix, type, h, suffix);
+}
+
+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);
+
+ return CHILD_OPS (reset_interest_for_hash, type, h);
+}
+
+int
+ipv6_get_data_locator (hicn_type_t type, const hicn_protocol_t * h,
+ ip46_address_t * ip_address)
+{
+ ip_address->ip6 = h->ipv6.daddr;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_set_data_locator (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * ip_address)
+{
+ h->ipv6.daddr = ip_address->ip6;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_get_data_name (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_t * name)
+{
+ name->ip6.prefix_as_ip6 = h->ipv6.saddr;
+#ifndef HICN_VPP_PLUGIN
+ name->type = HNT_CONTIGUOUS_V6;
+ name->len = HICN_V6_NAME_LEN;
+#endif /* HICN_VPP_PLUGIN */
+ return CHILD_OPS (get_data_name_suffix, type, h, &(name->ip6.suffix));
+}
+
+int
+ipv6_set_data_name (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_t * name)
+{
+ h->ipv6.saddr = name->ip6.prefix_as_ip6;
+ return CHILD_OPS (set_data_name_suffix, type, h, &(name->ip6.suffix));
+}
+
+int
+ipv6_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (get_data_name_suffix, type, h, suffix);
+}
+
+int
+ipv6_set_data_name_suffix (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_suffix_t * suffix)
+{
+ return CHILD_OPS (set_data_name_suffix, type, h, suffix);
+}
+
+int
+ipv6_get_data_pathlabel (hicn_type_t type, const hicn_protocol_t * h,
+ u32 * pathlabel)
+{
+ return CHILD_OPS (get_data_pathlabel, type, h, pathlabel);
+}
+
+int
+ipv6_set_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
+ const u32 pathlabel)
+{
+ return CHILD_OPS (set_data_pathlabel, type, h, pathlabel);
+}
+
+int
+ipv6_update_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_faceid_t face_id)
+{
+ return CHILD_OPS (update_data_pathlabel, type, h, face_id);
+}
+
+int
+ipv6_reset_data_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ /* IP: Set everithing to 0 up to destination address */
+ memset (&h->ipv6, 0, 8);
+ /* Clears destination address */
+ memset (&(h->ipv6.daddr), 0, 16);
+
+ return CHILD_OPS (reset_data_for_hash, type, h);
+}
+
+int
+ipv6_get_lifetime (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_lifetime_t * lifetime)
+{
+ return CHILD_OPS (get_lifetime, type, h, lifetime);
+}
+
+int
+ipv6_set_lifetime (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_lifetime_t lifetime)
+{
+ return CHILD_OPS (set_lifetime, type, h, lifetime);
+}
+
+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)
+ {
+ int rc = ipv6_get_payload_length (type, h, &payload_length);
+ if (rc < 0)
+ return rc;
+ }
+
+ /* Ignore the payload if payload_length = ~0 */
+ if (payload_length == ~0)
+ {
+ payload_length = 0;
+ }
+
+ /* Build pseudo-header */
+ ipv6_pseudo_header_t psh;
+ psh.ip_src = h->ipv6.saddr;
+ psh.ip_dst = h->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.zeros = 0;
+ psh.zero = 0;
+ psh.protocol = h->ipv6.nxt;
+
+ /* Compute partial checksum based on pseudo-header */
+ if (partial_csum != 0)
+ {
+ partial_csum = ~partial_csum;
+ }
+ partial_csum = csum (&psh, IPV6_PSHDRLEN, partial_csum);
+
+ return CHILD_OPS (update_checksums, type, h, partial_csum, payload_length);
+}
+
+int
+ipv6_verify_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)
+ {
+ int rc = ipv6_get_payload_length (type, h, &payload_length);
+ if (rc < 0)
+ return rc;
+ }
+
+ /* Build pseudo-header */
+ ipv6_pseudo_header_t pseudo;
+ pseudo.ip_src = h->ipv6.saddr;
+ pseudo.ip_dst = h->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.zeros = 0;
+ pseudo.zero = 0;
+ pseudo.protocol = h->ipv6.nxt;
+
+ /* Compute partial checksum based on pseudo-header */
+ partial_csum = csum (&pseudo, IPV6_PSHDRLEN, 0);
+
+ return CHILD_OPS (verify_checksums, type, h, partial_csum, payload_length);
+}
+
+int
+ipv6_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new,
+ ip46_address_t * addr_old)
+{
+ // ASSERT(addr_old == NULL);
+ addr_old->ip6 = h->ipv6.saddr;
+ h->ipv6.saddr = addr_new->ip6;
+
+ return CHILD_OPS (rewrite_interest, type, h, addr_new, addr_old);
+}
+
+int
+ipv6_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new, ip46_address_t * addr_old,
+ const hicn_faceid_t face_id)
+{
+ // ASSERT(addr_old == NULL);
+ addr_old->ip6 = h->ipv6.daddr;
+ h->ipv6.daddr = addr_new->ip6;
+
+ return CHILD_OPS (rewrite_data, type, h, addr_new, addr_old, face_id);
+}
+
+int
+ipv6_get_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * header_length)
+{
+ *header_length = IPV6_HDRLEN + ntohs (h->ipv6.len);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_get_current_header_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * header_length)
+{
+ *header_length = IPV6_HDRLEN;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_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 = IPV6_HDRLEN + child_header_length;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_get_payload_length (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * payload_length)
+{
+ 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;
+}
+
+int
+ipv6_set_payload_length (hicn_type_t type, hicn_protocol_t * h,
+ size_t payload_length)
+{
+ 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 (payload_length + child_header_length);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+ipv6_get_signature_size (hicn_type_t type, const hicn_protocol_t * h,
+ size_t * signature_size)
+{
+ return CHILD_OPS (get_signature_size, type, h, signature_size);
+}
+
+int
+ipv6_set_signature_size (hicn_type_t type, hicn_protocol_t * h,
+ size_t signature_size)
+{
+ return CHILD_OPS (set_signature_size, type, h, signature_size);
+}
+
+int
+ipv6_set_signature_timestamp(hicn_type_t type, hicn_protocol_t * h,
+ uint64_t signature_timestamp)
+{
+ return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+ipv6_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t * h,
+ uint64_t * signature_timestamp)
+{
+ return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+ipv6_set_validation_algorithm (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t validation_algorithm)
+{
+ return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+ipv6_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t * h,
+ uint8_t * validation_algorithm)
+{
+ return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+ipv6_set_key_id (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t *key_id)
+{
+ return CHILD_OPS (set_key_id, type, h, key_id);
+}
+
+int
+ipv6_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);
+}
+
+DECLARE_HICN_OPS (ipv6);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/ipv6.h b/lib/src/protocol/ipv6.h
new file mode 100755
index 000000000..28a1aa47f
--- /dev/null
+++ b/lib/src/protocol/ipv6.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HICN_PROTOCOL_IPV6_H
+#define HICN_PROTOCOL_IPV6_H
+
+#include "../common.h"
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ u32 version_class_flow; /* version, traffic class and 20 bits of flow-ID */
+ u16 len; /* payload length */
+ u8 nxt; /* next header */
+ u8 hlim; /* hop limit */
+ };
+ u8 vfc; /* 4 bits version, top 4 bits class */
+ };
+ ip6_address_t saddr; /* source address */
+ ip6_address_t daddr; /* destination address */
+} _ipv6_header_t;
+
+
+#define IPV6_HDRLEN sizeof(_ipv6_header_t)
+
+typedef struct
+{
+ ip6_address_t ip_src;
+ ip6_address_t ip_dst;
+ u32 size;
+ u16 zeros;
+ u8 zero;
+ u8 protocol;
+} ipv6_pseudo_header_t;
+
+#define IPV6_PSHDRLEN sizeof(ipv6_pseudo_header_t)
+
+/* Default field values */
+#define IPV6_DEFAULT_VERSION 6
+#define IPV6_DEFAULT_TRAFFIC_CLASS 0
+#define IPV6_DEFAULT_FLOW_LABEL 0
+#define IPV6_DEFAULT_PAYLOAD_LENGTH 0
+
+#endif
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/tcp.c b/lib/src/protocol/tcp.c
new file mode 100755
index 000000000..2afc4f6f4
--- /dev/null
+++ b/lib/src/protocol/tcp.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "tcp.h"
+
+#include "../error.h"
+#include "../ops.h"
+
+#define TCP_DEFAULT_SRC_PORT 0x8000
+#define TCP_DEFAULT_DST_PORT 0x0080
+#define TCP_DEFAULT_WINDOW_SIZE 0 // In [2, 65535]
+#define TCP_DEFAULT_HLEN 20
+#define TCP_DEFAULT_DATA_OFFSET_RES (TCP_DEFAULT_HLEN >> 2) << 4
+#define TCP_DEFAULT_CWR 0
+#define TCP_DEFAULT_ECE 0
+#define TCP_DEFAULT_URG 0
+#define TCP_DEFAULT_ACK 0
+#define TCP_DEFAULT_PSH 0
+#define TCP_DEFAULT_RST 0
+#define TCP_DEFAULT_SYN 1
+#define TCP_DEFAULT_FIN 0
+
+DECLARE_get_interest_locator (tcp, UNEXPECTED);
+DECLARE_set_interest_locator (tcp, UNEXPECTED);
+DECLARE_get_interest_name (tcp, UNEXPECTED);
+DECLARE_set_interest_name (tcp, UNEXPECTED);
+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);
+
+int
+tcp_init_packet_header (hicn_type_t type, hicn_protocol_t * h)
+{
+ h->tcp = (_tcp_header_t)
+ {
+ .sport = htons (TCP_DEFAULT_SRC_PORT),.dport =
+ htons (TCP_DEFAULT_DST_PORT),.seq = 0,.seq_ack =
+ 0,.data_offset_and_reserved = TCP_DEFAULT_DATA_OFFSET_RES,.flags =
+ TCP_DEFAULT_CWR << 7 | TCP_DEFAULT_ECE << 6 | TCP_DEFAULT_URG << 5 |
+ TCP_DEFAULT_ACK << 4 | TCP_DEFAULT_PSH << 3 | TCP_DEFAULT_RST << 2 |
+ TCP_DEFAULT_SYN << 1 | TCP_DEFAULT_FIN << 0,.window =
+ htons (TCP_DEFAULT_WINDOW_SIZE),.csum = 0,.urg_ptr = 65000,};
+
+ return CHILD_OPS (init_packet_header, type, h);
+}
+
+int
+tcp_get_interest_name_suffix (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_suffix_t * suffix)
+{
+ *suffix = ntohl (h->tcp.name_suffix);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_suffix_t * suffix)
+{
+ h->tcp.name_suffix = htonl (*suffix);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ memset (&(h->tcp), 0, 4);
+ memset (&(h->tcp.seq_ack), 0, 12);
+
+ return CHILD_OPS (reset_interest_for_hash, type, h);
+}
+
+
+int
+tcp_get_data_name_suffix (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_name_suffix_t * suffix)
+{
+ *suffix = ntohl (h->tcp.name_suffix);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_set_data_name_suffix (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_name_suffix_t * suffix)
+{
+ h->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)
+{
+ *pathlabel = h->tcp.seq_ack;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_set_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
+ const u32 pathlabel)
+{
+ h->tcp.seq_ack = pathlabel;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_update_data_pathlabel (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_faceid_t face_id)
+{
+ hicn_pathlabel_t pl =
+ (hicn_pathlabel_t) ((h->tcp.pathlabel & HICN_PATH_LABEL_MASK) >> (32 -
+ HICN_PATH_LABEL_SIZE));
+ hicn_pathlabel_t new_pl;
+
+ update_pathlabel (pl, face_id, &new_pl);
+ h->tcp.pathlabel = new_pl;
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_reset_data_for_hash (hicn_type_t type, hicn_protocol_t * h)
+{
+ memset (&(h->tcp), 0, 4);
+ memset (&(h->tcp.seq_ack), 0, 12);
+
+ return CHILD_OPS (reset_data_for_hash, type, h);
+}
+
+
+int
+tcp_get_lifetime (hicn_type_t type, const hicn_protocol_t * h,
+ hicn_lifetime_t * lifetime)
+{
+ *lifetime =
+ ntohs (h->tcp.urg_ptr) << (h->tcp.data_offset_and_reserved & 0xF);
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_set_lifetime (hicn_type_t type, hicn_protocol_t * h,
+ const hicn_lifetime_t lifetime)
+{
+ u8 multiplier = 0;
+ u32 lifetime_scaled = lifetime;
+
+ if (PREDICT_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 & ~0xF) | HICN_MAX_LIFETIME_MULTIPLIER;
+ return HICN_LIB_ERROR_NONE;
+ }
+
+ while (lifetime_scaled > HICN_MAX_LIFETIME_SCALED
+ && multiplier <= HICN_MAX_LIFETIME_MULTIPLIER)
+ {
+ multiplier++;
+ lifetime_scaled = lifetime_scaled >> 1;
+ }
+
+ h->tcp.urg_ptr = htons (lifetime_scaled);
+ h->tcp.data_offset_and_reserved =
+ (h->tcp.data_offset_and_reserved & ~0xF) | multiplier;
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_update_checksums (hicn_type_t type, hicn_protocol_t * h, u16 partial_csum,
+ size_t payload_length)
+{
+ h->tcp.csum = 0;
+
+ if (PREDICT_TRUE (partial_csum != 0))
+ {
+ partial_csum = ~partial_csum;
+ }
+
+ h->tcp.csum = csum (h, TCP_HDRLEN + payload_length, partial_csum);
+
+ return CHILD_OPS (update_checksums, type, h, 0, payload_length);
+}
+
+int
+tcp_verify_checksums (hicn_type_t type, hicn_protocol_t * h, u16 partial_csum,
+ size_t payload_length)
+{
+ if (csum (h, TCP_HDRLEN + payload_length, ~partial_csum) != 0)
+ return HICN_LIB_ERROR_CORRUPTED_PACKET;
+ return CHILD_OPS (verify_checksums, type, h, 0, payload_length);
+}
+
+#define TCP_OFFSET_MASK 13
+#define TCP_OFFSET_DATA_OFFSET 12
+#define TCP_OFFSET_IN_BITS_DATA_OFFSET 0
+#define TCP_OFFSET_IN_BITS_RESERVED 4
+#define TCP_OFFSET_IN_BITS_NS 7
+
+#define TCP_DEFAULT_SRC_PORT 0x8000
+#define TCP_DEFAULT_DST_PORT 0x0080
+#define TCP_DEFAULT_WINDOW_SIZE 0 // In [2, 65535]
+#define TCP_DEFAULT_DATA_OFFSET 5 // Size of the TCP header in words (= 4 bytes). Must be greater or equal than 5.
+#define TCP_DEFAULT_CWR 0
+#define TCP_DEFAULT_ECE 0
+#define TCP_DEFAULT_URG 0
+#define TCP_DEFAULT_ACK 0
+#define TCP_DEFAULT_PSH 0
+#define TCP_DEFAULT_RST 0
+#define TCP_DEFAULT_SYN 1
+#define TCP_DEFAULT_FIN 0
+
+int
+tcp_rewrite_interest (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new,
+ ip46_address_t * addr_old)
+{
+ u16 *tcp_checksum = &(h->tcp.csum);
+
+ /*
+ * Padding fields are set to zero so we can apply checksum on the
+ * 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);
+ */
+ u16 csum = ip_csum_sub_even (*tcp_checksum, h->ipv6.saddr.as_u64[0]);
+ csum = ip_csum_sub_even (csum, h->ipv6.saddr.as_u64[1]);
+ csum = ip_csum_add_even (csum, h->ipv6.saddr.as_u64[0]);
+ csum = ip_csum_add_even (csum, h->ipv6.saddr.as_u64[1]);
+
+ *tcp_checksum = ip_csum_fold (csum);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_rewrite_data (hicn_type_t type, hicn_protocol_t * h,
+ const ip46_address_t * addr_new, ip46_address_t * addr_old,
+ const hicn_faceid_t face_id)
+{
+ u16 *tcp_checksum = &(h->tcp.csum);
+
+ /*
+ * Padding fields are set to zero so we can apply checksum on the
+ * 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);
+ */
+ u16 csum = ip_csum_sub_even (*tcp_checksum, addr_old->ip6.as_u64[0]);
+ csum = ip_csum_sub_even (*tcp_checksum, addr_old->ip6.as_u64[1]);
+ 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->tcp.pathlabel);
+ tcp_update_data_pathlabel (type, h, face_id);
+ csum = ip_csum_add_even (csum, h->tcp.pathlabel);
+
+ *tcp_checksum = ip_csum_fold (csum);
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+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,
+ size_t * signature_size)
+{
+ return CHILD_OPS (get_signature_size, type, h, signature_size);
+}
+
+int
+tcp_set_signature_size (hicn_type_t type, hicn_protocol_t * h,
+ size_t signature_size)
+{
+ return CHILD_OPS (set_signature_size, type, h, signature_size);
+}
+
+int
+tcp_set_signature_timestamp(hicn_type_t type, hicn_protocol_t * h,
+ uint64_t signature_timestamp)
+{
+ return CHILD_OPS (set_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+tcp_get_signature_timestamp (hicn_type_t type, const hicn_protocol_t * h,
+ uint64_t * signature_timestamp)
+{
+ return CHILD_OPS (get_signature_timestamp, type, h, signature_timestamp);
+}
+
+int
+tcp_set_validation_algorithm (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t validation_algorithm)
+{
+ return CHILD_OPS (set_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+tcp_get_validation_algorithm (hicn_type_t type, const hicn_protocol_t * h,
+ uint8_t * validation_algorithm)
+{
+ return CHILD_OPS (get_validation_algorithm, type, h, validation_algorithm);
+}
+
+int
+tcp_set_key_id (hicn_type_t type, hicn_protocol_t * h,
+ uint8_t *key_id)
+{
+ return CHILD_OPS (set_key_id, type, h, key_id);
+}
+
+int
+tcp_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);
+}
+
+DECLARE_HICN_OPS (tcp);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/tcp.h b/lib/src/protocol/tcp.h
new file mode 100755
index 000000000..68f4bf8f9
--- /dev/null
+++ b/lib/src/protocol/tcp.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HICN_PROTOCOL_TCP_H
+#define HICN_PROTOCOL_TCP_H
+
+#include "../base.h"
+#include "../common.h"
+#include "../name.h"
+
+/*
+ * 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 __attribute__ ((packed))
+{
+ u16 sport;
+ u16 dport;
+ union
+ {
+ u32 seq;
+ hicn_name_suffix_t name_suffix;
+ };
+ union
+ {
+ u32 seq_ack;
+ struct
+ {
+ hicn_pathlabel_t pathlabel;
+ u8 pad[3];
+ };
+ };
+
+ union
+ {
+ struct
+ {
+ u8 data_offset_and_reserved;
+ u8 flags;
+ };
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ struct
+ {
+ u16 reserved:4;
+ u16 doff:4;
+ u16 fin:1;
+ u16 syn:1;
+ u16 rst:1;
+ u16 psh:1;
+ u16 ack:1;
+ u16 urg:1;
+ u16 ece:1;
+ u16 cwr:1;
+ };
+ struct
+ { /* __ denotes unchanged bitfields */
+ u16 timescale:4;
+ u16 __doff:4;
+ u16 __fin:1;
+ u16 __syn:1;
+ u16 __rst:1;
+ u16 sig:1;
+ u16 __ack:1;
+ u16 man:1;
+ u16 id:1;
+ u16 __cwr:1;
+ };
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ struct
+ {
+ u16 doff:4;
+ u16 reserved:4;
+ u16 cwr:1;
+ u16 ece:1;
+ u16 urg:1;
+ u16 ack:1;
+ u16 psh:1;
+ u16 rst:1;
+ u16 syn:1;
+ u16 fin:1;
+ };
+ struct
+ {
+ u16 __doff:4;
+ u16 timescale:4;
+ u16 __cwr:1;
+ u16 id:1 u16 man:1;
+ u16 __ack:1;
+ u16 sig:1;
+ u16 __rst:1;
+ u16 __syn:1;
+ u16 __fin:1;
+ };
+#endif
+ };
+ union
+ {
+ u16 window;
+ u16 ldr;
+ };
+ u16 csum;
+ union
+ {
+ u16 urg_ptr;
+ u16 lifetime;
+ };
+} _tcp_header_t;
+
+#define TCP_HDRLEN sizeof(_tcp_header_t)
+
+#ifndef HICN_VPP_PLUGIN
+
+/* TCP flags bit 0 first. */
+#define foreach_tcp_flag \
+ _ (FIN) /**< No more data from sender. */ \
+ _ (SYN) /**< Synchronize sequence numbers. */ \
+ _ (RST) /**< Reset the connection. */ \
+ _ (PSH) /**< Push function. */ \
+ _ (ACK) /**< Ack field significant. */ \
+ _ (URG) /**< Urgent pointer field significant. */ \
+ _ (ECE) /**< ECN-echo. Receiver got CE packet */ \
+ _ (CWR) /**< Sender reduced congestion window */
+
+enum
+{
+#define _(f) TCP_FLAG_BIT_##f,
+ foreach_tcp_flag
+#undef _
+ TCP_N_FLAG_BITS,
+};
+
+enum
+{
+#define _(f) TCP_FLAG_##f = 1 << TCP_FLAG_BIT_##f,
+ foreach_tcp_flag
+#undef _
+};
+
+#endif /* HICN_VPP_PLUGIN */
+
+// get_data_name_suffix
+// name->ip4.suffix = h->v4.tcp.seq;
+
+
+#endif /* HICN_PROTOCOL_TCP_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/lib/src/protocol/udp.h b/lib/src/protocol/udp.h
new file mode 100755
index 000000000..58cd65095
--- /dev/null
+++ b/lib/src/protocol/udp.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HICN_PROTOCOL_UDP_H
+#define HICN_PROTOCOL_UDP_H
+
+typedef struct
+{
+ u16 src_port;
+ u16 dst_port;
+ u16 length;
+ u16 checksum;
+} _udp_header_t;
+
+#define UDP_HDRLEN sizeof(_udp_header_t)
+
+#endif /* HICN_PROTOCOL_UDP_H */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */