summaryrefslogtreecommitdiffstats
path: root/lib/src/mapme.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src/mapme.c')
-rwxr-xr-xlib/src/mapme.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/lib/src/mapme.c b/lib/src/mapme.c
new file mode 100755
index 000000000..e4c5ee1f2
--- /dev/null
+++ b/lib/src/mapme.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file mapme.c
+ * @brief Implementation of MAP-Me anchorless producer mobility management.
+ */
+
+#include "mapme.h"
+#include "common.h"
+#include "error.h"
+
+#include "protocol/ipv4.h"
+#include "protocol/ipv6.h"
+
+size_t
+hicn_mapme_v4_create_packet (u8 * buf, const hicn_prefix_t * prefix,
+ const mapme_params_t * params)
+{
+ hicn_mapme_v4_header_t *mh = (hicn_mapme_v4_header_t *) buf;
+ /* *INDENT-OFF* */
+ *mh = (hicn_mapme_v4_header_t) {
+ .ip = {
+ .version_ihl = (IPV4_DEFAULT_VERSION << 4) | (0x0f & IPV4_DEFAULT_IHL),
+ .tos = IPV4_DEFAULT_TOS,
+ .len = HICN_MAPME_V4_HDRLEN,
+ .id = htons(IPV4_DEFAULT_ID),
+ .frag_off = htons(IPV4_DEFAULT_FRAG_OFF),
+ .ttl = HICN_MAPME_TTL,
+ .protocol = IPPROTO_ICMP,
+ .csum = 0,
+ .saddr.as_u32 = 0,
+ .daddr = prefix->name.ip4,
+ },
+ .icmp = {
+ .type = ((params->type == UPDATE) || (params->type == NOTIFICATION))
+ ? HICN_MAPME_ICMP_TYPE_IPV4
+ : HICN_MAPME_ICMP_TYPE_ACK_IPV4,
+ .code = HICN_MAPME_ICMP_CODE,
+ .csum = 0,
+ },
+ .icmp_rd = {
+ .ip = prefix->name.ip4,
+ },
+ .seq = htonl(params->seq),
+ .len = prefix->len,
+ };
+ /* *INDENT-ON* */
+
+ return HICN_MAPME_V4_HDRLEN;
+}
+
+size_t
+hicn_mapme_v6_create_packet (u8 * buf, const hicn_prefix_t * prefix,
+ const mapme_params_t * params)
+{
+ hicn_mapme_v6_header_t *mh = (hicn_mapme_v6_header_t *) buf;
+ /* *INDENT-OFF* */
+ *mh = (hicn_mapme_v6_header_t) {
+ .ip = {
+ .saddr = {{0}},
+ .daddr = prefix->name.ip6,
+ .version_class_flow = htonl(
+ (IPV6_DEFAULT_VERSION << 28) |
+ (IPV6_DEFAULT_TRAFFIC_CLASS << 20) |
+ (IPV6_DEFAULT_FLOW_LABEL & 0xfffff)),
+ .len = htons(HICN_MAPME_V6_HDRLEN - IPV6_HDRLEN),
+ .nxt = IPPROTO_ICMPV6,
+ .hlim = HICN_MAPME_TTL,
+ },
+ .icmp = {
+ .type = ((params->type == UPDATE) || (params->type == NOTIFICATION))
+ ? HICN_MAPME_ICMP_TYPE_IPV6
+ : HICN_MAPME_ICMP_TYPE_ACK_IPV6,
+ .code = HICN_MAPME_ICMP_CODE,
+ .csum = 0,
+ },
+ .icmp_rd = {
+ .res = 0,
+ .tgt = prefix->name.ip6,
+ .dst = prefix->name.ip6,
+ },
+ .seq = htonl(params->seq),
+ .len = prefix->len,
+ };
+ /* *INDENT-ON* */
+ return HICN_MAPME_V6_HDRLEN;
+}
+
+size_t
+hicn_mapme_create_packet (u8 * buf, const hicn_prefix_t * prefix,
+ const mapme_params_t * params)
+{
+ /* We currently ignore subsequent protocol definitions */
+ if (PREDICT_TRUE (params->protocol == IPPROTO_IPV6))
+ return hicn_mapme_v6_create_packet (buf, prefix, params);
+ else
+ return hicn_mapme_v4_create_packet (buf, prefix, params);
+}
+
+size_t
+hicn_mapme_v4_create_ack (u8 * buf, const mapme_params_t * params)
+{
+ ip4_address_t tmp; // tmp storage for swapping IP addresses for ACK
+
+ hicn_mapme_v4_header_t *mh = (hicn_mapme_v4_header_t *) buf;
+ tmp = mh->ip.daddr;
+ mh->ip.daddr = mh->ip.saddr;
+ mh->ip.saddr = tmp;
+ mh->ip.ttl = HICN_MAPME_TTL;
+ mh->icmp.type = (params->type == UPDATE) ? UPDATE_ACK : NOTIFICATION_ACK;
+ mh->icmp.csum = 0;
+
+ return HICN_MAPME_V4_HDRLEN;
+}
+
+size_t
+hicn_mapme_v6_create_ack (u8 * buf, const mapme_params_t * params)
+{
+ ip6_address_t tmp; // tmp storage for swapping IP addresses for ACK
+
+ hicn_mapme_v6_header_t *mh = (hicn_mapme_v6_header_t *) buf;
+ tmp = mh->ip.daddr;
+ mh->ip.daddr = mh->ip.saddr;
+ mh->ip.saddr = tmp;
+ mh->ip.hlim = HICN_MAPME_TTL;
+ mh->icmp.type = (params->type == UPDATE) ? UPDATE_ACK : NOTIFICATION_ACK;
+ mh->icmp.csum = 0;
+
+ return HICN_MAPME_V6_HDRLEN;
+}
+
+size_t
+hicn_mapme_create_ack (u8 * buf, const mapme_params_t * params)
+{
+ /* We currently ignore subsequent protocol definitions */
+ if (PREDICT_TRUE (params->protocol == IPPROTO_IPV6))
+ return hicn_mapme_v6_create_ack (buf, params);
+ else
+ return hicn_mapme_v4_create_ack (buf, params);
+}
+
+int
+hicn_mapme_v4_parse_packet (const u8 * packet, hicn_prefix_t * prefix,
+ mapme_params_t * params)
+{
+ hicn_mapme_v4_header_t *mh = (hicn_mapme_v4_header_t *) packet;
+
+ /* *INDENT-OFF* */
+ *prefix = (hicn_prefix_t) {
+ .name = {
+ .ip4 = HICN_MAPME_TYPE_IS_IU (mh->icmp.type) ? mh->ip.daddr : mh->ip.saddr,
+ },
+ .len = mh->len,
+ };
+
+ *params = (mapme_params_t) {
+ .protocol = IPPROTO_IP,
+ .type = (mh->icmp.type == HICN_MAPME_ICMP_TYPE_IPV4) ? UPDATE : UPDATE_ACK,
+ .seq = ntohl (mh->seq),
+ };
+ /* *INDENT-ON* */
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_mapme_v6_parse_packet (const u8 * packet, hicn_prefix_t * prefix,
+ mapme_params_t * params)
+{
+ hicn_mapme_v6_header_t *mh = (hicn_mapme_v6_header_t *) packet;
+
+ /* *INDENT-OFF* */
+ *prefix = (hicn_prefix_t) {
+ .name = {
+ .ip6 = HICN_MAPME_TYPE_IS_IU (mh->icmp.type) ? mh->ip.daddr : mh->ip.saddr,
+ },
+ .len = mh->len,
+ };
+
+ *params = (mapme_params_t) {
+ .protocol = IPPROTO_IPV6,
+ .type = (mh->icmp.type == HICN_MAPME_ICMP_TYPE_IPV6) ? UPDATE : UPDATE_ACK,
+ .seq = ntohl (mh->seq),
+ };
+ /* *INDENT-ON* */
+
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+hicn_mapme_parse_packet (const u8 * packet, hicn_prefix_t * prefix,
+ mapme_params_t * params)
+{
+ switch (HICN_IP_VERSION (packet))
+ {
+ case 4:
+ return hicn_mapme_v4_parse_packet (packet, prefix, params);
+ case 6:
+ return hicn_mapme_v6_parse_packet (packet, prefix, params);
+ default:
+ return HICN_LIB_ERROR_UNEXPECTED;
+ }
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */