summaryrefslogtreecommitdiffstats
path: root/hicn-light/src/config
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar+fdio@cisco.com>2019-01-17 13:47:57 +0100
committerLuca Muscariello <lumuscar+fdio@cisco.com>2019-01-17 16:32:51 +0100
commitbac3da61644515f05663789b122554dc77549286 (patch)
tree898210bc8e70371d77de7d446a26c5dd4fd1165a /hicn-light/src/config
parentd5165246787301d0f13b646fda5e8a8567aef5ac (diff)
This is the first commit of the hicn projectv19.01
Change-Id: I6f2544ad9b9f8891c88cc4bcce3cf19bd3cc863f Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'hicn-light/src/config')
-rwxr-xr-xhicn-light/src/config/CMakeLists.txt97
-rwxr-xr-xhicn-light/src/config/commandOps.c72
-rwxr-xr-xhicn-light/src/config/commandOps.h126
-rwxr-xr-xhicn-light/src/config/commandParser.c216
-rwxr-xr-xhicn-light/src/config/commandParser.h196
-rwxr-xr-xhicn-light/src/config/commandReturn.h43
-rwxr-xr-xhicn-light/src/config/configuration.c1076
-rwxr-xr-xhicn-light/src/config/configuration.h152
-rwxr-xr-xhicn-light/src/config/configurationFile.c300
-rwxr-xr-xhicn-light/src/config/configurationFile.h93
-rwxr-xr-xhicn-light/src/config/configurationListeners.c535
-rwxr-xr-xhicn-light/src/config/configurationListeners.h62
-rwxr-xr-xhicn-light/src/config/controlAdd.c94
-rwxr-xr-xhicn-light/src/config/controlAdd.h32
-rwxr-xr-xhicn-light/src/config/controlAddConnection.c390
-rwxr-xr-xhicn-light/src/config/controlAddConnection.h31
-rwxr-xr-xhicn-light/src/config/controlAddListener.c178
-rwxr-xr-xhicn-light/src/config/controlAddListener.h30
-rwxr-xr-xhicn-light/src/config/controlAddPunting.c154
-rwxr-xr-xhicn-light/src/config/controlAddPunting.h22
-rwxr-xr-xhicn-light/src/config/controlAddRoute.c157
-rwxr-xr-xhicn-light/src/config/controlAddRoute.h30
-rwxr-xr-xhicn-light/src/config/controlCache.c91
-rwxr-xr-xhicn-light/src/config/controlCache.h22
-rwxr-xr-xhicn-light/src/config/controlCacheClear.c84
-rwxr-xr-xhicn-light/src/config/controlCacheClear.h30
-rwxr-xr-xhicn-light/src/config/controlCacheServe.c103
-rwxr-xr-xhicn-light/src/config/controlCacheServe.h22
-rwxr-xr-xhicn-light/src/config/controlCacheStore.c103
-rwxr-xr-xhicn-light/src/config/controlCacheStore.h22
-rwxr-xr-xhicn-light/src/config/controlList.c97
-rwxr-xr-xhicn-light/src/config/controlList.h30
-rwxr-xr-xhicn-light/src/config/controlListConnections.c160
-rwxr-xr-xhicn-light/src/config/controlListConnections.h30
-rwxr-xr-xhicn-light/src/config/controlListInterfaces.c76
-rwxr-xr-xhicn-light/src/config/controlListInterfaces.h31
-rwxr-xr-xhicn-light/src/config/controlListListeners.c141
-rwxr-xr-xhicn-light/src/config/controlListListeners.h31
-rwxr-xr-xhicn-light/src/config/controlListRoutes.c154
-rwxr-xr-xhicn-light/src/config/controlListRoutes.h29
-rwxr-xr-xhicn-light/src/config/controlMapMe.c94
-rwxr-xr-xhicn-light/src/config/controlMapMe.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeDiscovery.c103
-rwxr-xr-xhicn-light/src/config/controlMapMeDiscovery.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeEnable.c101
-rwxr-xr-xhicn-light/src/config/controlMapMeEnable.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeRetx.c94
-rwxr-xr-xhicn-light/src/config/controlMapMeRetx.h22
-rwxr-xr-xhicn-light/src/config/controlMapMeTimescale.c97
-rwxr-xr-xhicn-light/src/config/controlMapMeTimescale.h22
-rwxr-xr-xhicn-light/src/config/controlQuit.c63
-rwxr-xr-xhicn-light/src/config/controlQuit.h29
-rwxr-xr-xhicn-light/src/config/controlRemove.c92
-rwxr-xr-xhicn-light/src/config/controlRemove.h29
-rwxr-xr-xhicn-light/src/config/controlRemoveConnection.c115
-rwxr-xr-xhicn-light/src/config/controlRemoveConnection.h31
-rwxr-xr-xhicn-light/src/config/controlRemovePunting.c76
-rwxr-xr-xhicn-light/src/config/controlRemovePunting.h27
-rwxr-xr-xhicn-light/src/config/controlRemoveRoute.c150
-rwxr-xr-xhicn-light/src/config/controlRemoveRoute.h31
-rwxr-xr-xhicn-light/src/config/controlRoot.c134
-rwxr-xr-xhicn-light/src/config/controlRoot.h31
-rwxr-xr-xhicn-light/src/config/controlSet.c88
-rwxr-xr-xhicn-light/src/config/controlSet.h29
-rwxr-xr-xhicn-light/src/config/controlSetDebug.c74
-rwxr-xr-xhicn-light/src/config/controlSetDebug.h30
-rwxr-xr-xhicn-light/src/config/controlSetStrategy.c183
-rwxr-xr-xhicn-light/src/config/controlSetStrategy.h22
-rwxr-xr-xhicn-light/src/config/controlSetWldr.c122
-rwxr-xr-xhicn-light/src/config/controlSetWldr.h22
-rwxr-xr-xhicn-light/src/config/controlState.c237
-rwxr-xr-xhicn-light/src/config/controlState.h233
-rwxr-xr-xhicn-light/src/config/controlUnset.c78
-rwxr-xr-xhicn-light/src/config/controlUnset.h29
-rwxr-xr-xhicn-light/src/config/controlUnsetDebug.c77
-rwxr-xr-xhicn-light/src/config/controlUnsetDebug.h30
-rwxr-xr-xhicn-light/src/config/symbolicNameTable.c175
-rwxr-xr-xhicn-light/src/config/symbolicNameTable.h131
78 files changed, 8309 insertions, 0 deletions
diff --git a/hicn-light/src/config/CMakeLists.txt b/hicn-light/src/config/CMakeLists.txt
new file mode 100755
index 000000000..5ce680bfc
--- /dev/null
+++ b/hicn-light/src/config/CMakeLists.txt
@@ -0,0 +1,97 @@
+# 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.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandOps.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandParser.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandReturn.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/symbolicNameTable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlState.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRoot.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddConnection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAdd.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationFile.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationListeners.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddRoute.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddListener.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListConnections.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlList.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListListeners.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListRoutes.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSet.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnset.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetDebug.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnsetDebug.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMe.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeEnable.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeDiscovery.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeTimescale.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheServe.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheStore.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheClear.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCache.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetStrategy.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetWldr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPunting.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePunting.h
+)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandOps.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/commandParser.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/configuration.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationFile.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/configurationListeners.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlState.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/symbolicNameTable.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAdd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddConnection.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddRoute.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddListener.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlList.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListConnections.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListListeners.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlListRoutes.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRoot.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSet.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetDebug.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnset.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlUnsetDebug.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMe.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeEnable.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeDiscovery.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeTimescale.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlMapMeRetx.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheServe.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheStore.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCacheClear.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlCache.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetStrategy.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlSetWldr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPunting.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePunting.c
+)
+
+set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/hicn-light/src/config/commandOps.c b/hicn-light/src/config/commandOps.c
new file mode 100755
index 000000000..027c86e0a
--- /dev/null
+++ b/hicn-light/src/config/commandOps.c
@@ -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.
+ */
+
+#include <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#ifndef __ANDROID__
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#else
+extern int errno;
+#endif
+#endif
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/commandOps.h>
+#include <src/config/commandParser.h>
+
+CommandOps *commandOps_Create(void *closure, const char *command,
+ void (*init)(CommandParser *parser,
+ CommandOps *ops),
+ CommandReturn (*execute)(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args),
+ void (*destroyer)(CommandOps **opsPtr)) {
+ parcAssertNotNull(command, "Parameter command must be non-null");
+ parcAssertNotNull(execute, "Parameter execute must be non-null");
+ CommandOps *ops = parcMemory_AllocateAndClear(sizeof(CommandOps));
+ parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(CommandOps));
+
+ ops->closure = closure;
+ ops->command = parcMemory_StringDuplicate(command, strlen(command) + 1);
+ ops->init = init;
+ ops->execute = execute;
+ ops->destroyer = destroyer;
+ return ops;
+}
+
+void commandOps_Destroy(CommandOps **opsPtr) {
+ parcAssertNotNull(opsPtr, "Parameter opsPtr must be non-null");
+ parcAssertNotNull(*opsPtr,
+ "Parameter opsPtr must dereference to non-null pointer");
+
+ CommandOps *ops = *opsPtr;
+ parcMemory_Deallocate((void **)&(ops->command));
+ // DO NOT call ops->destroyer, we are one!
+ parcMemory_Deallocate((void **)&ops);
+
+ *opsPtr = NULL;
+}
diff --git a/hicn-light/src/config/commandOps.h b/hicn-light/src/config/commandOps.h
new file mode 100755
index 000000000..6428a3ebf
--- /dev/null
+++ b/hicn-light/src/config/commandOps.h
@@ -0,0 +1,126 @@
+/*
+ * 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 command_Ops.h
+ * @brief The function structure defining a CLI command
+ *
+ * The function structure that defines a CLI command. Each command will return
+ * one of these which defines how to run the command.
+ *
+ */
+
+#ifndef command_Ops_h
+#define command_Ops_h
+
+#include <parc/algol/parc_List.h>
+
+#include <src/config/commandReturn.h>
+
+// forward reference
+struct command_parser;
+
+struct command_ops;
+typedef struct command_ops CommandOps;
+
+/**
+ * @typedef CommandOps
+ * @abstract Each command implements a CommandOps
+ * @constant closure is a user-specified pointer for any state the user needs
+ * @constant command The text string of the command, must be the spelled out
+ * string, e.g. "help list routes"
+ * @constant init A function to call to initialize the command at program
+ * startup
+ * @constant execute A function to call to execute the command
+ * @constant destroyer A function to call to release the command
+ * @discussion
+ * Typically, the root of the thee has an Init function that then initilizes
+ * the rest of the tree. For example:
+ *
+ * @code
+ * const CommandOps control_Root = {
+ * .closure = NULL,
+ * .command = "", // empty string for root
+ * .init = control_Root_Init,
+ * .execute = control_Root_Execute
+ * .destroyer = NULL
+ * };
+ * @endcode
+ *
+ * The control_Root_Init function will then begin adding the subtree under root.
+ * For example:
+ *
+ * @code
+ * const CommandOps control_Add = {
+ * .closure = NULL,
+ * .command = "add",
+ * .init = control_Add_Init,
+ * .execute = control_Add_Execute,
+ * .destroyer = NULL
+ * };
+ *
+ * static void
+ * control_Root_Init(ControlState *state, CommandOps *ops)
+ * {
+ * controlState_RegisterCommand(state, &control_Add);
+ * }
+ * @endcode
+ */
+struct command_ops {
+ void *closure;
+ char *command;
+ void (*init)(struct command_parser *parser, CommandOps *ops);
+ CommandReturn (*execute)(struct command_parser *parser, CommandOps *ops,
+ PARCList *args);
+ void (*destroyer)(CommandOps **opsPtr);
+};
+
+/**
+ * A helper function to create the pubically defined CommandOps.
+ *
+ * Retruns allocated memory of the command
+ *
+ * @param [in] command The string is copied
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandOps *commandOps_Create(
+ void *closure, const char *command,
+ void (*init)(struct command_parser *parser, CommandOps *ops),
+ CommandReturn (*execute)(struct command_parser *parser, CommandOps *ops,
+ PARCList *args),
+ void (*destroyer)(CommandOps **opsPtr));
+
+/**
+ * De-allocates the memory of the CommandOps and the copied command string
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void commandOps_Destroy(CommandOps **opsPtr);
+#endif // command_Ops_h
diff --git a/hicn-light/src/config/commandParser.c b/hicn-light/src/config/commandParser.c
new file mode 100755
index 000000000..84d273c9d
--- /dev/null
+++ b/hicn-light/src/config/commandParser.c
@@ -0,0 +1,216 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Time.h>
+#include <parc/algol/parc_TreeRedBlack.h>
+
+#include <src/config/commandParser.h>
+
+#ifndef __ANDROID__
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#else
+extern int errno;
+#endif
+#endif
+
+struct command_parser {
+ // key = command, value = CommandOps
+ PARCTreeRedBlack *commandTree;
+ bool debugFlag;
+};
+
+static int _stringCompare(const void *key1, const void *key2) {
+ return strcasecmp((const char *)key1, (const char *)key2);
+}
+
+CommandParser *commandParser_Create(void) {
+ CommandParser *state = parcMemory_AllocateAndClear(sizeof(CommandParser));
+ parcAssertNotNull(state, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(CommandParser));
+
+ state->commandTree = parcTreeRedBlack_Create(_stringCompare, // key compare
+ NULL, // key free
+ NULL, // key copy
+ NULL, // value equals
+ NULL, // value free
+ NULL // value copy
+ );
+ state->debugFlag = false;
+ return state;
+}
+
+void commandParser_Destroy(CommandParser **parserPtr) {
+ CommandParser *parser = *parserPtr;
+
+ // destroy every element if it has a destroyer
+ PARCArrayList *values = parcTreeRedBlack_Values(parser->commandTree);
+ if (values) {
+ for (int i = 0; i < parcArrayList_Size(values); i++) {
+ CommandOps *ops = parcArrayList_Get(values, i);
+ parcTreeRedBlack_Remove(parser->commandTree, ops->command);
+ if (ops->destroyer) {
+ ops->destroyer(&ops);
+ }
+ }
+ parcArrayList_Destroy(&values);
+ }
+
+ parcTreeRedBlack_Destroy(&parser->commandTree);
+
+ parcMemory_Deallocate((void **)&parser);
+ *parserPtr = NULL;
+}
+
+void commandParser_SetDebug(CommandParser *state, bool debugFlag) {
+ state->debugFlag = debugFlag;
+}
+
+bool commandParser_GetDebug(CommandParser *state) { return state->debugFlag; }
+
+void commandParser_RegisterCommand(CommandParser *state, CommandOps *ops) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ parcAssertNotNull(ops, "Parameter ops must be non-null");
+ parcAssertNotNull(ops->command, "Operation command string must be non-null");
+
+ void *exists = parcTreeRedBlack_Get(state->commandTree, ops->command);
+ parcAssertNull(exists, "Command '%s' already exists in the tree %p\n",
+ ops->command, (void *)exists);
+
+ parcTreeRedBlack_Insert(state->commandTree, (void *)ops->command,
+ (void *)ops);
+
+ // if the command being registered asked for an init function to be called,
+ // call it
+ if (ops->init != NULL) {
+ ops->init(state, ops);
+ }
+}
+
+static PARCList *parseStringIntoTokens(const char *originalString) {
+ PARCList *list =
+ parcList(parcArrayList_Create(parcArrayList_StdlibFreeFunction),
+ PARCArrayListAsPARCList);
+
+ char *token;
+
+ char *tofree =
+ parcMemory_StringDuplicate(originalString, strlen(originalString) + 1);
+ char *string = tofree;
+
+ while ((token = strsep(&string, " \t\n")) != NULL) {
+ if (strlen(token) > 0) {
+ parcList_Add(list, strdup(token));
+ }
+ }
+
+ parcMemory_Deallocate((void **)&tofree);
+
+ return list;
+}
+
+/**
+ * Matches the user arguments to available commands, returning the command or
+ * NULL if not found
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static CommandOps *commandParser_MatchCommand(CommandParser *state,
+ PARCList *args) {
+ // Find the longest matching prefix command.
+ // Pretty wildly inefficient
+
+ size_t longest_token_count = 0;
+ char *longest_command = NULL;
+
+ PARCArrayList *commands = parcTreeRedBlack_Keys(state->commandTree);
+ for (int i = 0; i < parcArrayList_Size(commands); i++) {
+ char *command = parcArrayList_Get(commands, i);
+ PARCList *command_tokens = parseStringIntoTokens(command);
+
+ // is it a prefix match?
+ if (parcList_Size(args) >= parcList_Size(command_tokens)) {
+ bool possible_match = true;
+ for (int i = 0; i < parcList_Size(command_tokens) && possible_match;
+ i++) {
+ const char *a = parcList_GetAtIndex(command_tokens, i);
+ const char *b = parcList_GetAtIndex(args, i);
+ if (strncasecmp(a, b, strlen(a) + 1) != 0) {
+ possible_match = false;
+ }
+ }
+
+ if (possible_match &&
+ parcList_Size(command_tokens) > longest_token_count) {
+ longest_token_count = parcList_Size(command_tokens);
+ longest_command = command;
+ }
+ }
+
+ parcList_Release(&command_tokens);
+ }
+
+ parcArrayList_Destroy(&commands);
+
+ if (longest_token_count == 0) {
+ return NULL;
+ } else {
+ CommandOps *ops = parcTreeRedBlack_Get(state->commandTree, longest_command);
+ parcAssertNotNull(ops, "Got null operations for command '%s'\n",
+ longest_command);
+ return ops;
+ }
+}
+
+CommandReturn commandParser_DispatchCommand(CommandParser *state,
+ PARCList *args) {
+ CommandOps *ops = commandParser_MatchCommand(state, args);
+
+ if (ops == NULL) {
+ printf("Command not found.\n");
+ return CommandReturn_Failure;
+ } else {
+ return ops->execute(state, ops, args);
+ }
+}
+
+bool commandParser_ContainsCommand(CommandParser *parser, const char *command) {
+ CommandOps *ops = parcTreeRedBlack_Get(parser->commandTree, command);
+ return (ops != NULL);
+}
diff --git a/hicn-light/src/config/commandParser.h b/hicn-light/src/config/commandParser.h
new file mode 100755
index 000000000..78e19e6e3
--- /dev/null
+++ b/hicn-light/src/config/commandParser.h
@@ -0,0 +1,196 @@
+/*
+ * 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 command_Parser.h
+ * @brief Creates a dictionary of commands and parses a command_line to match
+ * against them
+ *
+ * A user creates individual CommandParserEntry that map a command_line to a
+ * function to execute. The CommandParser then does a longest-matching prefix
+ * match of a command_line to the dictionary of commands and executes the
+ * appropriate command.
+ *
+ */
+
+#ifndef command_parser_h
+#define command_parser_h
+
+#include <src/config/commandOps.h>
+#include <src/config/commandReturn.h>
+
+struct command_parser;
+typedef struct command_parser CommandParser;
+
+/**
+ * controlState_Create
+ *
+ * Creates the global state for the Control program
+ *
+ * @return non-null A command parser
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandParser *commandParser_Create(void);
+
+/**
+ * Destroys the control state, closing all network connections
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void commandParser_Destroy(CommandParser **statePtr);
+
+/**
+ * Registers a CommandOps with the system.
+ *
+ * Each command has its complete command prefix in the "command" field.
+ * RegisterCommand will put these command prefixes in to a tree and then match
+ * what a user types against the longest-matching prefix in the tree. If
+ * there's a match, it will call the "execute" function.
+ *
+ * When the parser is destroyed, each command's destroyer function will be
+ * called.
+ *
+ * @param [in] state An allocated ControlState
+ * @param [in] command The command to register with the system
+ *
+ * Example:
+ * @code
+ * static ControlReturn
+ * control_Root_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Root Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * static ControlReturn
+ * control_FooBar_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Foo Bar Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * const CommandOps control_Root = {
+ * .closure = NULL,
+ * .command = "", // empty string for root
+ * .init = NULL,
+ * .execute = control_Root_Execute
+ * };
+ *
+ * const CommandOps control_FooBar = {
+ * .closure = NULL,
+ * .command = "foo bar", // empty string for root
+ * .init = NULL,
+ * .execute = control_FooBar_Execute
+ * };
+ *
+ * void startup(void)
+ * {
+ * ControlState *state = controlState_Create("happy", "day");
+ * controlState_RegisterCommand(state, control_FooBar);
+ * controlState_RegisterCommand(state, control_Root);
+ *
+ * // this executes "root"
+ * controlState_DispatchCommand(state, "foo");
+ * controlState_Destroy(&state);
+ * }
+ * @endcode
+ */
+void commandParser_RegisterCommand(CommandParser *state, CommandOps *command);
+
+/**
+ * Performs a longest-matching prefix of the args to the command tree
+ *
+ * The command tree is created with controlState_RegisterCommand.
+ *
+ * @param [in] state The allocated ControlState
+ * @param [in] args Each command_line word parsed to the ordered list
+ *
+ * @return CommandReturn_Success the command was successful
+ * @return CommandReturn_Failure the command failed or was not found
+ * @return CommandReturn_Exit the command indicates that the interactive mode
+ * should exit
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandReturn commandParser_DispatchCommand(CommandParser *state,
+ PARCList *args);
+
+/**
+ * Sets the Debug mode, which will print out much more information.
+ *
+ * Prints out much more diagnostic information about what hicn-light controller
+ * is doing. yes, you would make a CommandOps to set and unset this :)
+ *
+ * @param [in] debugFlag true means to print debug info, false means to turn it
+ * off
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void commandParser_SetDebug(CommandParser *state, bool debugFlag);
+
+/**
+ * Returns the debug state of ControlState
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool commandParser_GetDebug(CommandParser *state);
+
+/**
+ * Checks if the command is registered
+ *
+ * Checks if the exact command given is registered. This is not a prefix match.
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return true The command is registered
+ * @return false The command is not registered
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool commandParser_ContainsCommand(CommandParser *parser, const char *command);
+#endif // command_parser_h
diff --git a/hicn-light/src/config/commandReturn.h b/hicn-light/src/config/commandReturn.h
new file mode 100755
index 000000000..16ee93db1
--- /dev/null
+++ b/hicn-light/src/config/commandReturn.h
@@ -0,0 +1,43 @@
+/*
+ * 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 command_Return.h
+ * @brief The return code used by CLI commands
+ *
+ * This return code is used throughout the command parser and command
+ * implementations to indicate success, failure, or if the program should exit.
+ *
+ */
+
+#ifndef command_return_h
+#define command_return_h
+
+/**
+ * @typedef ControlReturn
+ * @abstract A command returns one of (SUCCESS, FAILURE, EXIT)
+ * @constant SUCCESS means the command succeeded
+ * @constant FAILURE indicates failure
+ * @constant EXIT means the command indicated that hicn-light controller should
+ * exit.
+ * @discussion <#Discussion#>
+ */
+typedef enum command_return {
+ CommandReturn_Success, // command returned success
+ CommandReturn_Failure, // command failure
+ CommandReturn_Exit // command indicates program should exit
+} CommandReturn;
+
+#endif // command_return_h
diff --git a/hicn-light/src/config/configuration.c b/hicn-light/src/config/configuration.c
new file mode 100755
index 000000000..cccd60620
--- /dev/null
+++ b/hicn-light/src/config/configuration.c
@@ -0,0 +1,1076 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_HashMap.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_String.h>
+
+#include <src/config/configurationListeners.h>
+#include <src/config/symbolicNameTable.h>
+
+#include <src/core/connection.h>
+#include <src/core/connectionTable.h>
+#include <src/core/forwarder.h>
+#include <src/core/system.h>
+#ifdef WITH_MAPME
+#include <src/core/mapMe.h>
+#endif /* WITH_MAPME */
+
+#include <src/io/streamConnection.h>
+
+#include <src/io/hicnTunnel.h>
+#include <src/io/tcpTunnel.h>
+#include <src/io/udpTunnel.h>
+
+#include <parc/algol/parc_Unsigned.h>
+#include <src/io/listener.h> //the listener list
+#include <src/io/listenerSet.h> // needed to print
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+#include <src/utils/address.h>
+
+#define ETHERTYPE 0x0801
+
+struct configuration {
+ Forwarder *forwarder;
+ Logger *logger;
+
+ size_t maximumContentObjectStoreSize;
+
+ // map from prefix (parcString) to strategy (parcString)
+ PARCHashMap *strategy_map;
+
+ // translates between a symblic name and a connection id
+ SymbolicNameTable *symbolicNameTable;
+};
+
+// ========================================================================================
+
+Configuration *configuration_Create(Forwarder *forwarder) {
+ parcAssertNotNull(forwarder, "Parameter hicn-fwd must be non-null");
+ Configuration *config = parcMemory_AllocateAndClear(sizeof(Configuration));
+ parcAssertNotNull(config, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(Configuration));
+ config->forwarder = forwarder;
+ config->logger = logger_Acquire(forwarder_GetLogger(forwarder));
+ config->maximumContentObjectStoreSize = 100000;
+ config->strategy_map = parcHashMap_Create();
+ config->symbolicNameTable = symbolicNameTable_Create();
+
+ return config;
+}
+
+void configuration_Destroy(Configuration **configPtr) {
+ parcAssertNotNull(configPtr, "Parameter must be non-null double poitner");
+ parcAssertNotNull(*configPtr,
+ "Parameter must dereference to non-null pointer");
+
+ Configuration *config = *configPtr;
+ logger_Release(&config->logger);
+ parcHashMap_Release(&(config->strategy_map));
+ symbolicNameTable_Destroy(&config->symbolicNameTable);
+ parcMemory_Deallocate((void **)&config);
+ *configPtr = NULL;
+}
+
+struct iovec *configuration_ProcessRegisterHIcnPrefix(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId) {
+ header_control_message *header = request[0].iov_base;
+ add_route_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+
+ if (strcmp(symbolicOrConnid, "SELF_ROUTE") == 0) {
+ success = forwarder_AddOrUpdateRoute(config->forwarder, control, ingressId);
+ } else if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input
+ unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL);
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+
+ // check if iconnID present in the fwd table
+ if (connectionTable_FindById(table, connid)) {
+ success = forwarder_AddOrUpdateRoute(config->forwarder, control, connid);
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections");
+ // failure
+ }
+
+ } else {
+ // case for symbolic as input: check if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ // connid = UINT_MAX when symbolicName is not found
+ if (connid != UINT32_MAX) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Add route resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+
+ success = forwarder_AddOrUpdateRoute(config->forwarder, control, connid);
+
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Warning,
+ __func__,
+ "Add route symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ }
+ // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_route_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(add_route_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessUnregisterHIcnPrefix(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ remove_route_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+
+ if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input
+ unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL);
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+
+ // check if interface index present in the fwd table
+ if (connectionTable_FindById(table, connid)) {
+ success = forwarder_RemoveRoute(config->forwarder, control, connid);
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections");
+ // failure
+ }
+
+ } else {
+ // case for symbolic as input: chech if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ // connid = UINT_MAX when symbolicName is not found
+ if (connid != UINT32_MAX) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Remove route resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+ success = forwarder_RemoveRoute(config->forwarder, control, connid);
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Warning,
+ __func__,
+ "Remove route symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ }
+ // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(remove_route_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(remove_route_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessRegistrationList(Configuration *config,
+ struct iovec *request) {
+ FibEntryList *fibList = forwarder_GetFibEntries(config->forwarder);
+
+ size_t payloadSize = fibEntryList_Length(fibList);
+ size_t pointerLocation = 0;
+ struct sockaddr_in tmpAddr;
+ struct sockaddr_in6 tmpAddr6;
+
+ // allocate payload, cast from void* to uint8_t* = bytes granularity
+ uint8_t *payloadResponse =
+ parcMemory_AllocateAndClear(sizeof(list_routes_command) * payloadSize);
+
+ for (size_t i = 0; i < fibEntryList_Length(fibList); i++) {
+ FibEntry *entry = (FibEntry *)fibEntryList_Get(fibList, i);
+ NameBitvector *prefix = name_GetContentName(fibEntry_GetPrefix(entry));
+ const NumberSet *nexthops = fibEntry_GetNexthops(entry);
+
+ if (numberSet_Length(nexthops) > 1) {
+ // payload extended, need reallocate, further entries via nexthops
+ payloadSize = payloadSize + numberSet_Length(nexthops) - 1;
+ payloadResponse = (uint8_t *)parcMemory_Reallocate(
+ payloadResponse, sizeof(list_routes_command) * payloadSize);
+ }
+
+ for (size_t j = 0; j < numberSet_Length(nexthops); j++) {
+ list_routes_command *listRouteCommand =
+ (list_routes_command *)(payloadResponse +
+ (pointerLocation *
+ sizeof(list_routes_command)));
+
+ Address *addressEntry = nameBitvector_ToAddress(prefix);
+ if (addressGetType(addressEntry) == ADDR_INET) {
+ addressGetInet(addressEntry, &tmpAddr);
+ listRouteCommand->addressType = ADDR_INET;
+ listRouteCommand->address.ipv4 = tmpAddr.sin_addr.s_addr;
+ } else if (addressGetType(addressEntry) == ADDR_INET6) {
+ addressGetInet6(addressEntry, &tmpAddr6);
+ listRouteCommand->addressType = ADDR_INET6;
+ listRouteCommand->address.ipv6 = tmpAddr6.sin6_addr;
+ }
+ listRouteCommand->connid = numberSet_GetItem(nexthops, j);
+ listRouteCommand->len = nameBitvector_GetLength(prefix);
+ listRouteCommand->cost = 1; // cost
+
+ pointerLocation++;
+ addressDestroy(&addressEntry);
+ }
+ }
+
+ // send response
+ header_control_message *header = request[0].iov_base;
+ header->messageType = RESPONSE_LIGHT;
+ header->length = payloadSize;
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = header;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len = sizeof(list_routes_command) * payloadSize;
+
+ return response;
+}
+
+static void configuration_SendResponse(Configuration *config, struct iovec *msg,
+ unsigned egressId) {
+ ConnectionTable *connectionTable =
+ forwarder_GetConnectionTable(config->forwarder);
+ const Connection *conn = connectionTable_FindById(connectionTable, egressId);
+ parcAssertNotNull(conn,
+ "Got null connection for control message we just received");
+
+ IoOperations *ops = connection_GetIoOperations(conn);
+ streamState_SendCommandResponse(ops, msg);
+}
+
+struct iovec *configuration_ProcessCreateTunnel(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ add_connection_command *control = request[1].iov_base;
+
+ bool success = false;
+ bool exists = true;
+
+ const char *symbolicName = control->symbolic;
+
+ Address *source = NULL;
+ Address *destination = NULL;
+
+ if (!symbolicNameTable_Exists(config->symbolicNameTable, symbolicName)) {
+ if (control->ipType == ADDR_INET) {
+ source =
+ utils_AddressFromInet(&control->localIp.ipv4, &control->localPort);
+ destination =
+ utils_AddressFromInet(&control->remoteIp.ipv4, &control->remotePort);
+ } else if (control->ipType == ADDR_INET6) {
+ source =
+ utils_AddressFromInet6(&control->localIp.ipv6, &control->localPort);
+ destination =
+ utils_AddressFromInet6(&control->remoteIp.ipv6, &control->remotePort);
+ } else {
+ printf("Invalid IP type.\n"); // will generate a Nack
+ }
+
+ AddressPair *pair = addressPair_Create(source, destination);
+ const Connection *conn = connectionTable_FindByAddressPair(
+ forwarder_GetConnectionTable(config->forwarder), pair);
+
+ addressPair_Release(&pair);
+
+ if (conn == NULL) {
+ // the connection does not exists (even without a name)
+ exists = false;
+ }
+ }
+
+ if (!exists) {
+ IoOperations *ops = NULL;
+ switch (control->connectionType) {
+ case TCP_CONN:
+ // logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ // __func__,
+ // "Unsupported tunnel protocol: TCP");
+ ops = tcpTunnel_Create(config->forwarder, source, destination);
+ break;
+ case UDP_CONN:
+ ops = udpTunnel_Create(config->forwarder, source, destination);
+ break;
+ case GRE_CONN:
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__, "Unsupported tunnel protocol: GRE");
+ break;
+#ifndef __APPLE__
+ case HICN_CONN:
+ ops = hicnTunnel_Create(config->forwarder, source, destination);
+ break;
+#endif /* __APPLE__ */
+ default:
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__, "Unsupported tunnel protocol: %d",
+ control->connectionType);
+ break;
+ }
+
+ if (ops != NULL) {
+ Connection *conn = connection_Create(ops);
+
+ connectionTable_Add(forwarder_GetConnectionTable(config->forwarder),
+ conn);
+ symbolicNameTable_Add(config->symbolicNameTable, symbolicName,
+ connection_GetConnectionId(conn));
+
+ success = true;
+
+ } else {
+ printf("failed, could not create IoOperations");
+ }
+
+ } else {
+ printf("failed, symbolic name or connextion already exist\n");
+ }
+
+ addressDestroy(&source);
+ addressDestroy(&destination);
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_connection_command));
+ } else { // NACK
+ response =
+ utils_CreateNack(header, control, sizeof(add_connection_command));
+ }
+
+ return response;
+}
+
+/**
+ * Add an IP-based tunnel.
+ *
+ * The call cal fail if the symbolic name is a duplicate. It could also fail if
+ * there's an problem creating the local side of the tunnel (i.e. the local
+ * socket address is not usable).
+ *
+ * @return true Tunnel added
+ * @return false Tunnel not added (an error)
+ */
+
+struct iovec *configuration_ProcessRemoveTunnel(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ remove_connection_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+
+ if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input
+ unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL);
+
+ // check if interface index present in the fwd table
+ //(it was missing and therefore caused a program crash)
+ if (connectionTable_FindById(table, connid)) {
+ // remove connection from the FIB
+ forwarder_RemoveConnectionIdFromRoutes(config->forwarder, connid);
+ // remove connection
+ connectionTable_RemoveById(table, connid);
+
+ success = true;
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections");
+ // failure
+ }
+
+ } else {
+ // case for symbolic as input
+ // chech if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ // connid = UINT_MAX when symbolicName is not found
+ if (connid != UINT32_MAX) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Remove connection resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+
+ // remove connection from the FIB
+ forwarder_RemoveConnectionIdFromRoutes(config->forwarder, connid);
+ // remove connection
+ connectionTable_RemoveById(table, connid);
+ // remove connection from symbolicNameTable since we have symbolic input
+ symbolicNameTable_Remove(config->symbolicNameTable, symbolicOrConnid);
+ success = true; // to write
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__,
+ "Remove connection symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ }
+ // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response =
+ utils_CreateAck(header, control, sizeof(remove_connection_command));
+ } else { // NACK
+ response =
+ utils_CreateNack(header, control, sizeof(remove_connection_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessConnectionList(Configuration *config,
+ struct iovec *request) {
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+ ConnectionList *connList = connectionTable_GetEntries(table);
+ struct sockaddr_in tmpAddr;
+ struct sockaddr_in6 tmpAddr6;
+
+ // allocate payload, cast from void* to uint8_t* fot bytes granularity
+ uint8_t *payloadResponse = parcMemory_AllocateAndClear(
+ sizeof(list_connections_command) * connectionList_Length(connList));
+
+ for (size_t i = 0; i < connectionList_Length(connList); i++) {
+ // Don't release original, it is not stored
+ Connection *original = connectionList_Get(connList, i);
+
+ const AddressPair *addressPair = connection_GetAddressPair(original);
+ Address *localAddress = addressCopy(addressPair_GetLocal(addressPair));
+ Address *remoteAddress = addressCopy(addressPair_GetRemote(addressPair));
+
+ // Fill payload by shifting and casting at each 'i' step.
+ list_connections_command *listConnectionsCommand =
+ (list_connections_command *)(payloadResponse +
+ (i * sizeof(list_connections_command)));
+
+ // set structure fields
+ listConnectionsCommand->connid = connection_GetConnectionId(original);
+ listConnectionsCommand->state =
+ connection_IsUp(original) ? IFACE_UP : IFACE_DOWN;
+ listConnectionsCommand->connectionData.connectionType =
+ ioOperations_GetConnectionType(connection_GetIoOperations(original));
+
+ if (addressGetType(localAddress) == ADDR_INET &&
+ addressGetType(remoteAddress) == ADDR_INET) {
+ listConnectionsCommand->connectionData.ipType = ADDR_INET;
+
+ // get local port/address
+ addressGetInet(localAddress, &tmpAddr);
+ listConnectionsCommand->connectionData.localPort = tmpAddr.sin_port;
+ listConnectionsCommand->connectionData.localIp.ipv4 =
+ tmpAddr.sin_addr.s_addr;
+ memset(&tmpAddr, 0, sizeof(tmpAddr));
+ // get remote port/address
+ addressGetInet(remoteAddress, &tmpAddr);
+ listConnectionsCommand->connectionData.remotePort = tmpAddr.sin_port;
+ listConnectionsCommand->connectionData.remoteIp.ipv4 =
+ tmpAddr.sin_addr.s_addr;
+
+ } else if (addressGetType(localAddress) == ADDR_INET6 &&
+ addressGetType(remoteAddress) == ADDR_INET6) {
+ listConnectionsCommand->connectionData.ipType = ADDR_INET6;
+
+ // get local port/address
+ addressGetInet6(localAddress, &tmpAddr6);
+ listConnectionsCommand->connectionData.localPort = tmpAddr6.sin6_port;
+ listConnectionsCommand->connectionData.localIp.ipv6 = tmpAddr6.sin6_addr;
+ memset(&tmpAddr6, 0, sizeof(tmpAddr6));
+ // get remote port/address
+ addressGetInet6(remoteAddress, &tmpAddr6);
+ listConnectionsCommand->connectionData.remotePort = tmpAddr6.sin6_port;
+ listConnectionsCommand->connectionData.remoteIp.ipv6 = tmpAddr6.sin6_addr;
+
+ } // no need further else, control on the addressed already done at the
+ // time of insertion in the connection table
+ addressDestroy(&localAddress);
+ addressDestroy(&remoteAddress);
+ }
+
+ // send response
+ header_control_message *header = request[0].iov_base;
+ header->messageType = RESPONSE_LIGHT;
+ header->length = (uint16_t)connectionList_Length(connList);
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = header;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len =
+ sizeof(list_connections_command) * connectionList_Length(connList);
+
+ return response;
+}
+
+struct iovec *configuration_ProcessListenersList(Configuration *config,
+ struct iovec *request) {
+ ListenerSet *listenerList = forwarder_GetListenerSet(config->forwarder);
+ struct sockaddr_in tmpAddr;
+ struct sockaddr_in6 tmpAddr6;
+
+ // allocate payload, cast from void* to uint8_t* fot bytes granularity
+ uint8_t *payloadResponse = parcMemory_AllocateAndClear(
+ sizeof(list_listeners_command) * listenerSet_Length(listenerList));
+
+ for (size_t i = 0; i < listenerSet_Length(listenerList); i++) {
+ ListenerOps *listenerEntry = listenerSet_Get(listenerList, i);
+
+ // Fill payload by shifting and casting at each 'i' step.
+ list_listeners_command *listListenersCommand =
+ (list_listeners_command *)(payloadResponse +
+ (i * sizeof(list_listeners_command)));
+
+ listListenersCommand->connid =
+ (uint32_t)listenerEntry->getInterfaceIndex(listenerEntry);
+ listListenersCommand->encapType =
+ (uint8_t)listenerEntry->getEncapType(listenerEntry);
+ if (addressGetType((const Address *)listenerEntry->getListenAddress(
+ listenerEntry)) == ADDR_INET) {
+ addressGetInet(
+ (const Address *)listenerEntry->getListenAddress(listenerEntry),
+ &tmpAddr);
+ listListenersCommand->addressType = ADDR_INET;
+ listListenersCommand->address.ipv4 = tmpAddr.sin_addr.s_addr;
+ listListenersCommand->port = tmpAddr.sin_port;
+ } else if (addressGetType((const Address *)listenerEntry->getListenAddress(
+ listenerEntry)) == ADDR_INET6) {
+ addressGetInet6(
+ (const Address *)listenerEntry->getListenAddress(listenerEntry),
+ &tmpAddr6);
+ listListenersCommand->addressType = ADDR_INET6;
+ listListenersCommand->address.ipv6 = tmpAddr6.sin6_addr;
+ listListenersCommand->port = tmpAddr6.sin6_port;
+ }
+ }
+
+ // send response
+ header_control_message *header = request[0].iov_base;
+ header->messageType = RESPONSE_LIGHT;
+ header->length = (uint16_t)listenerSet_Length(listenerList);
+
+ struct iovec *response =
+ parcMemory_AllocateAndClear(sizeof(struct iovec) * 2);
+
+ response[0].iov_base = header;
+ response[0].iov_len = sizeof(header_control_message);
+ response[1].iov_base = payloadResponse;
+ response[1].iov_len =
+ sizeof(list_listeners_command) * listenerSet_Length(listenerList);
+
+ return response;
+}
+
+struct iovec *configuration_ProcessCacheStore(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ ;
+ cache_store_command *control = request[1].iov_base;
+ ;
+
+ bool success = false;
+
+ switch (control->activate) {
+ case ACTIVATE_ON:
+ forwarder_SetChacheStoreFlag(config->forwarder, true);
+ if (forwarder_GetChacheStoreFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ case ACTIVATE_OFF:
+ forwarder_SetChacheStoreFlag(config->forwarder, false);
+ if (!forwarder_GetChacheStoreFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ struct iovec *response;
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(cache_store_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(cache_store_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessCacheServe(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ cache_serve_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ switch (control->activate) {
+ case ACTIVATE_ON:
+ forwarder_SetChacheServeFlag(config->forwarder, true);
+ if (forwarder_GetChacheServeFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ case ACTIVATE_OFF:
+ forwarder_SetChacheServeFlag(config->forwarder, false);
+ if (!forwarder_GetChacheServeFlag(config->forwarder)) {
+ success = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ struct iovec *response;
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(cache_store_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(cache_store_command));
+ }
+
+ return response;
+}
+
+struct iovec *configuration_ProcessCacheClear(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+
+ forwarder_ClearCache(config->forwarder);
+
+ struct iovec *response = utils_CreateAck(header, NULL, 0);
+ return response;
+}
+
+size_t configuration_GetObjectStoreSize(Configuration *config) {
+ return config->maximumContentObjectStoreSize;
+}
+
+void _configuration_StoreFwdStrategy(Configuration *config, const char *prefix,
+ strategy_type strategy) {
+ PARCString *prefixStr = parcString_Create(prefix);
+ PARCUnsigned *strategyValue = parcUnsigned_Create((unsigned)strategy);
+ parcHashMap_Put(config->strategy_map, prefixStr, strategyValue);
+ parcUnsigned_Release(&strategyValue);
+ parcString_Release(&prefixStr);
+}
+
+struct iovec *configuration_SetWldr(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ set_wldr_command *control = request[1].iov_base;
+ ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder);
+ Connection *conn = NULL;
+ bool success = false;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+
+ if (utils_IsNumber(symbolicOrConnid)) {
+ // case for connid as input: check if connID present in the fwd table
+ conn = (Connection *)connectionTable_FindById(
+ table, (unsigned)strtold(symbolicOrConnid, NULL));
+ if (conn) {
+ success = true;
+ } else {
+ logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO,
+ PARCLogLevel_Error, __func__,
+ "ConnID not found, check list connections"); // failure
+ }
+ } else {
+ // case for symbolic as input: check if symbolic name can be resolved
+ unsigned connid =
+ symbolicNameTable_Get(config->symbolicNameTable, symbolicOrConnid);
+ if (connid != UINT32_MAX) {
+ conn = (Connection *)connectionTable_FindById(table, connid);
+ if (conn) {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Debug)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Debug,
+ __func__, "Set wldr resolve name '%s' to connid %u",
+ symbolicOrConnid, connid);
+ }
+ success = true;
+ }
+ } else {
+ if (logger_IsLoggable(config->logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(config->logger, LoggerFacility_Config, PARCLogLevel_Error,
+ __func__, "Symbolic name '%s' could not be resolved",
+ symbolicOrConnid);
+ } // failure
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) {
+ switch (control->activate) {
+ case ACTIVATE_ON:
+ connection_EnableWldr(conn);
+ response = utils_CreateAck(header, control, sizeof(set_wldr_command));
+ break;
+
+ case ACTIVATE_OFF:
+ connection_DisableWldr(conn);
+ response = utils_CreateAck(header, control, sizeof(set_wldr_command));
+ break;
+
+ default: // received wrong value
+ response = utils_CreateNack(header, control, sizeof(set_wldr_command));
+ break;
+ }
+ } else {
+ response = utils_CreateNack(header, control, sizeof(set_wldr_command));
+ }
+
+ return response;
+}
+
+strategy_type configuration_GetForwardingStrategy(Configuration *config,
+ const char *prefix) {
+ PARCString *prefixStr = parcString_Create(prefix);
+ const unsigned *val = parcHashMap_Get(config->strategy_map, prefixStr);
+ parcString_Release(&prefixStr);
+
+ if (val == NULL) {
+ return LAST_STRATEGY_VALUE;
+ } else {
+ return (strategy_type)*val;
+ }
+}
+
+struct iovec *configuration_SetForwardingStrategy(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ set_strategy_command *control = request[1].iov_base;
+
+ const char *prefix = utils_PrefixLenToString(
+ control->addressType, &control->address, &control->len);
+ strategy_type strategy = control->strategyType;
+ strategy_type existingFwdStrategy =
+ configuration_GetForwardingStrategy(config, prefix);
+
+ if (existingFwdStrategy == LAST_STRATEGY_VALUE ||
+ strategy != existingFwdStrategy) {
+ // means such a new strategy is not present in the hash table or has to be
+ // updated
+ _configuration_StoreFwdStrategy(config, prefix, strategy);
+ Name *hicnPrefix = name_CreateFromAddress(control->addressType,
+ control->address, control->len);
+ forwarder_SetStrategy(config->forwarder, hicnPrefix, strategy);
+ name_Release(&hicnPrefix);
+ }
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(set_strategy_command));
+
+ return response;
+}
+
+void configuration_SetObjectStoreSize(Configuration *config,
+ size_t maximumObjectCount) {
+ config->maximumContentObjectStoreSize = maximumObjectCount;
+
+ forwarder_SetContentObjectStoreSize(config->forwarder,
+ config->maximumContentObjectStoreSize);
+}
+
+Forwarder *configuration_GetForwarder(const Configuration *config) {
+ return config->forwarder;
+}
+
+Logger *configuration_GetLogger(const Configuration *config) {
+ return config->logger;
+}
+
+struct iovec *configuration_MapMeEnable(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_activator_command *control = request[1].iov_base;
+ const char *stateString[2] = {"on", "off"};
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(composer,
+ "The mapme enable setting received is: %s",
+ stateString[control->activate]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_activator_command));
+
+ return response;
+}
+
+struct iovec *configuration_MapMeDiscovery(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_activator_command *control = request[1].iov_base;
+ const char *stateString[2] = {"on", "off"};
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(composer,
+ "The mapme discovery setting received is: %s",
+ stateString[control->activate]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_activator_command));
+
+ return response;
+}
+
+struct iovec *configuration_MapMeTimescale(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_timing_command *control = request[1].iov_base;
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(composer,
+ "The mapme timescale value received is: %u",
+ control->timePeriod);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_timing_command));
+
+ return response;
+}
+
+struct iovec *configuration_MapMeRetx(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ mapme_timing_command *control = request[1].iov_base;
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ parcBufferComposer_Format(
+ composer, "The mapme retransmission time value received is: %u",
+ control->timePeriod);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+
+ struct iovec *response =
+ utils_CreateAck(header, control, sizeof(mapme_timing_command));
+
+ return response;
+}
+
+// ===========================
+// Main functions that deal with receiving commands, executing them, and sending
+// ACK/NACK
+
+struct iovec *configuration_DispatchCommand(Configuration *config,
+ command_id command,
+ struct iovec *control,
+ unsigned ingressId) {
+ struct iovec *response = NULL;
+
+ switch (command) {
+ case ADD_LISTENER:
+ response = configurationListeners_Add(config, control, ingressId);
+ break;
+
+ case ADD_CONNECTION:
+ response = configuration_ProcessCreateTunnel(config, control);
+ break;
+
+ case LIST_CONNECTIONS:
+ response = configuration_ProcessConnectionList(config, control);
+ break;
+
+ case ADD_ROUTE:
+ response =
+ configuration_ProcessRegisterHIcnPrefix(config, control, ingressId);
+ break;
+
+ case LIST_ROUTES:
+ response = configuration_ProcessRegistrationList(config, control);
+ break;
+
+ case REMOVE_CONNECTION:
+ response = configuration_ProcessRemoveTunnel(config, control);
+ break;
+
+ case REMOVE_ROUTE:
+ response = configuration_ProcessUnregisterHIcnPrefix(config, control);
+ break;
+
+ case CACHE_STORE:
+ response = configuration_ProcessCacheStore(config, control);
+ break;
+
+ case CACHE_SERVE:
+ response = configuration_ProcessCacheServe(config, control);
+ break;
+
+ case CACHE_CLEAR:
+ response = configuration_ProcessCacheClear(config, control);
+ break;
+
+ case SET_STRATEGY:
+ response = configuration_SetForwardingStrategy(config, control);
+ break;
+
+ case SET_WLDR:
+ response = configuration_SetWldr(config, control);
+ break;
+
+ case ADD_PUNTING:
+ response = configurationListeners_AddPunting(config, control, ingressId);
+ break;
+
+ case LIST_LISTENERS:
+ response = configuration_ProcessListenersList(config, control);
+ break;
+
+ case MAPME_ENABLE:
+ response = configuration_MapMeEnable(config, control);
+ break;
+
+ case MAPME_DISCOVERY:
+ response = configuration_MapMeDiscovery(config, control);
+ break;
+
+ case MAPME_TIMESCALE:
+ response = configuration_MapMeTimescale(config, control);
+ break;
+
+ case MAPME_RETX:
+ response = configuration_MapMeRetx(config, control);
+ break;
+
+ default:
+ break;
+ }
+
+ return response;
+}
+
+void configuration_ReceiveCommand(Configuration *config, command_id command,
+ struct iovec *request, unsigned ingressId) {
+ parcAssertNotNull(config, "Parameter config must be non-null");
+ parcAssertNotNull(request, "Parameter request must be non-null");
+ struct iovec *response =
+ configuration_DispatchCommand(config, command, request, ingressId);
+ configuration_SendResponse(config, response, ingressId);
+
+ switch (command) {
+ case LIST_CONNECTIONS:
+ case LIST_ROUTES: // case LIST_INTERFACES: case ETC...:
+ parcMemory_Deallocate(
+ &response[1]
+ .iov_base); // deallocate payload only if generated at fwd side
+ break;
+ default:
+ break;
+ }
+
+ // deallocate received request. It coincides with response[0].iov_base memory
+ // parcMemory_Deallocate(&request); //deallocate header and payload (if
+ // same sent by controller)
+ parcMemory_Deallocate(&response); // deallocate iovec pointer
+}
diff --git a/hicn-light/src/config/configuration.h b/hicn-light/src/config/configuration.h
new file mode 100755
index 000000000..2bf66c0b1
--- /dev/null
+++ b/hicn-light/src/config/configuration.h
@@ -0,0 +1,152 @@
+/*
+ * 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 configuration.h
+ * @brief hicn-light configuration, such as in-band commands or CLI
+ *
+ * Manages all user configuration of the system, such as from the CLI or web
+ * interface It remembers the user commands and will be able to write out a
+ * config file.
+ *
+ */
+
+#ifndef configuration_h
+#define configuration_h
+
+#include <src/utils/commands.h>
+#include <src/core/logger.h>
+
+struct configuration;
+typedef struct configuration Configuration;
+
+struct forwarder;
+typedef struct forwarder Forwarder;
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+Configuration *configuration_Create(Forwarder *forwarder);
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configuration_Destroy(Configuration **configPtr);
+
+void configuration_SetupAllListeners(Configuration *config, uint16_t port,
+ const char *localPath);
+
+void configuration_ReceiveCommand(Configuration *config, command_id command,
+ struct iovec *request, unsigned ingressId);
+
+/**
+ * Returns the configured size of the content store
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @retval <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+size_t configuration_GetObjectStoreSize(Configuration *config);
+
+/**
+ * Sets the size of the content store (in objects, not bytes)
+ *
+ * Must be set before starting the forwarder
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configuration_SetObjectStoreSize(Configuration *config,
+ size_t maximumContentObjectCount);
+
+strategy_type configuration_GetForwardingStrategy(Configuration *config,
+ const char *prefix);
+
+/**
+ * Returns the Forwarder that owns the Configuration
+ *
+ * Returns the hicn-light Forwarder. Used primarily by associated classes in
+ * the configuration group.
+ *
+ * @param [in] config An allocated Configuration
+ *
+ * @return non-null The owning Forwarder
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+Forwarder *configuration_GetForwarder(const Configuration *config);
+
+/**
+ * Returns the logger used by the Configuration subsystem
+ *
+ * Returns the logger specified when the Configuration was created.
+ *
+ * @param [in] config An allocated Configuration
+ *
+ * @retval non-null The logger
+ * @retval null An error
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+Logger *configuration_GetLogger(const Configuration *config);
+
+struct iovec *configuration_DispatchCommand(Configuration *config,
+ command_id command,
+ struct iovec *control,
+ unsigned ingressId);
+
+#endif // configuration_h
diff --git a/hicn-light/src/config/configurationFile.c b/hicn-light/src/config/configurationFile.c
new file mode 100755
index 000000000..eab8f9362
--- /dev/null
+++ b/hicn-light/src/config/configurationFile.c
@@ -0,0 +1,300 @@
+/*
+ * 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 <ctype.h>
+#include <errno.h>
+#include <src/config.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_ArrayList.h>
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/configuration.h>
+#include <src/config/configurationFile.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlState.h>
+
+struct configuration_file {
+ Forwarder *forwarder;
+ const char *filename;
+ FILE *fh;
+
+ size_t linesRead;
+
+ // our custom state machine.
+ ControlState *controlState;
+};
+
+/*
+ * Called by a command to dispatch the correct command
+ */
+struct iovec *_writeRead(ControlState *state, struct iovec *msg) {
+ ConfigurationFile *configFile =
+ (ConfigurationFile *)controlState_GetUserdata(state);
+
+ parcAssertNotNull(msg, "Parameter msg must be non-null");
+ struct iovec *response = configuration_DispatchCommand(
+ forwarder_GetConfiguration(configFile->forwarder),
+ ((header_control_message *)msg[0].iov_base)->commandID, msg, 0);
+
+ return response;
+}
+
+/**
+ * Removes leading whitespace (space + tab).
+ *
+ * If the string is all whitespace, the return value will point to the
+ * terminating '\0'.
+ *
+ * @param [in] str A null-terminated c-string
+ *
+ * @retval non-null A pointer in to string of the first non-whitespace
+ *
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static char *_stripLeadingWhitespace(char *str) {
+ while (isspace(*str)) {
+ str++;
+ }
+ return str;
+}
+
+/**
+ * Removes trailing whitespace
+ *
+ * Inserts a NULL after the last non-whitespace character, modiyfing the input
+ * string.
+ *
+ * @param [in] str A null-terminated c-string
+ *
+ * @return non-null A pointer to the input string
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+static char *_stripTrailingWhitespace(char *str) {
+ char *p = str + strlen(str) - 1;
+ while (p > str && isspace(*p)) {
+ p--;
+ }
+
+ // cap it. If no whitespace, p+1 == str + strlen(str), so will overwrite the
+ // current null. If all whitespace p+1 == str+1. For an empty string, p+1 =
+ // str.
+ *(p + 1) = 0;
+
+ // this does not catch the case where the entire string is whitespace
+ if (p == str && isspace(*p)) {
+ *p = 0;
+ }
+
+ return str;
+}
+
+/**
+ * Removed leading and trailing whitespace
+ *
+ * Modifies the input string (may add a NULL at the end). Will return
+ * a pointer to the first non-whitespace character or the terminating NULL.
+ *
+ * @param [in] str A null-terminated c-string
+ *
+ * @return non-null A pointer in to the input string
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+static char *_trim(char *str) {
+ return _stripTrailingWhitespace(_stripLeadingWhitespace(str));
+}
+
+/**
+ * Parse a string in to a PARCList with one word per element
+ *
+ * The string passed will be modified by inserting NULLs after each token.
+ *
+ * @param [in] str A c-string (will be modified)
+ *
+ * @retval non-null A PARCList where each item is a single word
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static PARCList *_parseArgs(char *str) {
+ PARCList *list =
+ parcList(parcArrayList_Create(NULL), PARCArrayListAsPARCList);
+
+ const char delimiters[] = " \t";
+
+ char *token;
+ while ((token = strsep(&str, delimiters)) != NULL) {
+ parcList_Add(list, token);
+ }
+
+ return list;
+}
+
+// =============================================================
+
+static void _destroy(ConfigurationFile **configFilePtr) {
+ ConfigurationFile *configFile = *configFilePtr;
+ parcMemory_Deallocate((void **)&configFile->filename);
+
+ if (configFile->fh != NULL) {
+ fclose(configFile->fh);
+ }
+
+ controlState_Destroy(&configFile->controlState);
+}
+
+parcObject_ExtendPARCObject(ConfigurationFile, _destroy, NULL, NULL, NULL, NULL,
+ NULL, NULL);
+
+parcObject_ImplementRelease(configurationFile, ConfigurationFile);
+
+ConfigurationFile *configurationFile_Create(Forwarder *forwarder,
+ const char *filename) {
+ parcAssertNotNull(forwarder, "Parameter hicn-fwd must be non-null");
+ parcAssertNotNull(filename, "Parameter filename must be non-null");
+
+ ConfigurationFile *configFile = parcObject_CreateInstance(ConfigurationFile);
+
+ if (configFile) {
+ configFile->linesRead = 0;
+ configFile->forwarder = forwarder;
+ configFile->filename =
+ parcMemory_StringDuplicate(filename, strlen(filename));
+ parcAssertNotNull(configFile->filename, "Could not copy string '%s'",
+ filename);
+
+ // setup the control state for the command parser: last parameter NULL
+ // because
+ // writeRead still not implemented from configuration file.
+ configFile->controlState =
+ controlState_Create(configFile, _writeRead, false);
+
+ // we do not register Help commands
+ controlState_RegisterCommand(configFile->controlState,
+ controlRoot_Create(configFile->controlState));
+
+ // open the file and make sure we can read it
+ configFile->fh = fopen(configFile->filename, "r");
+
+ if (configFile->fh) {
+ if (logger_IsLoggable(forwarder_GetLogger(forwarder),
+ LoggerFacility_Config, PARCLogLevel_Debug)) {
+ logger_Log(forwarder_GetLogger(forwarder), LoggerFacility_Config,
+ PARCLogLevel_Debug, __func__, "Open config file %s",
+ configFile->filename);
+ }
+ } else {
+ if (logger_IsLoggable(forwarder_GetLogger(forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error)) {
+ logger_Log(forwarder_GetLogger(forwarder), LoggerFacility_Config,
+ PARCLogLevel_Error, __func__,
+ "Could not open config file %s: (%d) %s",
+ configFile->filename, errno, strerror(errno));
+ }
+
+ // failure cleanup the object -- this nulls it so final return null be
+ // NULL
+ configurationFile_Release(&configFile);
+ }
+ }
+ return configFile;
+}
+
+bool configurationFile_Process(ConfigurationFile *configFile) {
+ parcAssertNotNull(configFile, "Parameter configFile must be non-null");
+
+ // default to a "true" return value and only set to false if we encounter an
+ // error.
+ bool success = true;
+
+#define BUFFERLEN 2048
+ char buffer[BUFFERLEN];
+
+ configFile->linesRead = 0;
+
+ // always clear errors and fseek to start of file in case we get called
+ // multiple times.
+ clearerr(configFile->fh);
+ rewind(configFile->fh);
+
+ while (success && fgets(buffer, BUFFERLEN, configFile->fh) != NULL) {
+ configFile->linesRead++;
+
+ char *stripedBuffer = _trim(buffer);
+ if (strlen(stripedBuffer) > 0) {
+ if (stripedBuffer[0] != '#') {
+ // not empty and not a comment
+
+ // _parseArgs will modify the string
+ char *copy =
+ parcMemory_StringDuplicate(stripedBuffer, strlen(stripedBuffer));
+ PARCList *args = _parseArgs(copy);
+ CommandReturn result =
+ controlState_DispatchCommand(configFile->controlState, args);
+
+ // we ignore EXIT from the configuration file
+ if (result == CommandReturn_Failure) {
+ if (logger_IsLoggable(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error)) {
+ logger_Log(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error, __func__,
+ "Error on input file %s line %d: %s",
+ configFile->filename, configFile->linesRead,
+ stripedBuffer);
+ }
+ success = false;
+ }
+ parcList_Release(&args);
+ parcMemory_Deallocate((void **)&copy);
+ }
+ }
+ }
+
+ if (ferror(configFile->fh)) {
+ if (logger_IsLoggable(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error)) {
+ logger_Log(forwarder_GetLogger(configFile->forwarder),
+ LoggerFacility_Config, PARCLogLevel_Error, __func__,
+ "Error on input file %s line %d: (%d) %s",
+ configFile->filename, configFile->linesRead, errno,
+ strerror(errno));
+ }
+ success = false;
+ }
+
+ return success;
+}
diff --git a/hicn-light/src/config/configurationFile.h b/hicn-light/src/config/configurationFile.h
new file mode 100755
index 000000000..54548191d
--- /dev/null
+++ b/hicn-light/src/config/configurationFile.h
@@ -0,0 +1,93 @@
+/*
+ * 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 configurationFile.h
+ * @brief Accepts a filename and provides a means to read it into Configuration
+ *
+ * Reads a configuration file and converts the lines in to configuration
+ * commands for use in Configuration.
+ *
+ * Accepts '#' lines as comments. Skips blank and whitespace-only lines.
+ *
+ */
+
+#ifndef configurationFile_h
+#define configurationFile_h
+
+#include <src/core/forwarder.h>
+
+struct configuration_file;
+typedef struct configuration_file ConfigurationFile;
+
+/**
+ * Creates a ConfigurationFile to prepare to process the file
+ *
+ * Prepares the object and opens the file. Makes sure we can read the file.
+ * Does not read the file or process any commands from the file.
+ *
+ * @param [in] hicn-light An allocated Forwarder to configure with the file
+ * @param [in] filename The file to use
+ *
+ * @retval non-null An allocated ConfigurationFile that is readable
+ * @retval null An error
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+ConfigurationFile *configurationFile_Create(Forwarder *forwarder,
+ const char *filename);
+
+/**
+ * Reads the configuration file line-by-line and issues commands to
+ * Configuration
+ *
+ * Reads the file line by line. Skips '#' and blank lines.
+ *
+ * Will stop on the first error. Lines already processed will not be un-done.
+ *
+ * @param [in] configFile An allocated ConfigurationFile
+ *
+ * @retval true The entire files was processed without error.
+ * @retval false There was an error in the file.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool configurationFile_Process(ConfigurationFile *configFile);
+
+// void configurationFile_ProcessForwardingStrategies(Configuration * config,
+// ConfigurationFile * configFile);
+
+/**
+ * Closes the underlying file and releases memory
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [in,out] configFilePtr An allocated ConfigurationFile that will be
+ * NULL'd as output
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configurationFile_Release(ConfigurationFile **configFilePtr);
+
+#endif /* defined(configurationFile_h) */
diff --git a/hicn-light/src/config/configurationListeners.c b/hicn-light/src/config/configurationListeners.c
new file mode 100755
index 000000000..be30e2a49
--- /dev/null
+++ b/hicn-light/src/config/configurationListeners.c
@@ -0,0 +1,535 @@
+/*
+ * 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 <arpa/inet.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/core/system.h>
+#include <src/utils/interfaceSet.h>
+#include <src/utils/punting.h>
+
+#include <src/config/configurationListeners.h>
+#include <src/io/hicnListener.h>
+#include <src/io/tcpListener.h>
+#include <src/io/udpListener.h>
+
+#include <src/utils/addressList.h>
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static bool _setupHIcnListenerOnInet4(Forwarder *forwarder,
+ const char *symbolic, Address *address) {
+ bool success = false;
+#ifndef __APPLE__
+ ListenerOps *ops =
+ hicnListener_CreateInet(forwarder, (char *)symbolic, address);
+ if (ops != NULL) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add HIcn listener %s to ListenerSet",
+ symbolic);
+ }
+#endif /* __APPLE__ */
+ return success;
+}
+
+static bool _setupHIcnListenerOnInet6(Forwarder *forwarder,
+ const char *symbolic, Address *address) {
+ bool success = false;
+#ifndef __APPLE__
+ ListenerOps *ops =
+ hicnListener_CreateInet6(forwarder, (char *)symbolic, address);
+ if (ops != NULL) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add HIcn listener %s to ListenerSet",
+ symbolic);
+ }
+#endif /* __APPLE__ */
+ return success;
+}
+
+bool configurationListeners_Remove(const Configuration *config) {
+ Logger *logger = configuration_GetLogger(config);
+ if (logger_IsLoggable(logger, LoggerFacility_Config, PARCLogLevel_Warning)) {
+ logger_Log(logger, LoggerFacility_Config, PARCLogLevel_Warning, __func__,
+ "Removing a listener not supported: ingress %u control %s");
+ }
+
+ return false;
+}
+
+bool _AddPuntingInet(const Configuration *config, Punting *punting,
+ unsigned ingressId) {
+#ifndef __APPLE__
+ struct sockaddr *addr = parcNetwork_SockAddress("0.0.0.0", 1234);
+ if (addr == NULL) {
+ printf("Error creating address\n");
+ return false;
+ }
+
+ Address *fakeAddr = addressCreateFromInet((struct sockaddr_in *)addr);
+
+ ListenerOps *listenerOps = listenerSet_Find(
+ forwarder_GetListenerSet(configuration_GetForwarder(config)), ENCAP_HICN,
+ fakeAddr);
+ addressDestroy(&fakeAddr);
+
+ if (listenerOps == NULL) {
+ printf("the main listener (IPV4) does not exists\n");
+ return false;
+ }
+
+ struct sockaddr_in puntingAddr;
+
+ Address *address = puntingGetAddress(punting);
+ if (address == NULL) return false;
+
+ bool res = addressGetInet(address, &puntingAddr);
+ if (!res) {
+ printf("unable to read the punting address\n");
+ return false;
+ }
+
+ char prefix[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &(puntingAddr.sin_addr), prefix, INET_ADDRSTRLEN);
+
+ char len[5];
+ sprintf(len, "%d", puntingPrefixLen(punting));
+
+ char *prefixStr =
+ malloc(strlen(prefix) + strlen(len) + 2); //+1 for the zero-terminator
+ if (prefixStr == NULL) {
+ printf("error while create the prefix string\n");
+ return false;
+ }
+ strcpy(prefixStr, prefix);
+ strcat(prefixStr, "/");
+ strcat(prefixStr, len);
+
+ res = hicnListener_Punting(listenerOps, prefixStr);
+ if (!res) {
+ printf("error while adding the punting rule\n");
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool _AddPuntingInet6(const Configuration *config, Punting *punting,
+ unsigned ingressId) {
+#ifndef __APPLE__
+ struct sockaddr *addr = parcNetwork_SockAddress("0::0", 1234);
+ if (addr == NULL) {
+ printf("Error creating address\n");
+ return false;
+ }
+
+ Address *fakeAddr = addressCreateFromInet6((struct sockaddr_in6 *)addr);
+
+ // comments:
+ // EncapType: I use the HIcn encap since the puting is available only for HIcn
+ // listeners LocalAddress: The only listern for which we need punting rules is
+ // the main one, which has no address
+ // so I create a fake empty address. This need to be consistent
+ // with the address set at creation time
+
+ ListenerOps *listenerOps = listenerSet_Find(
+ forwarder_GetListenerSet(configuration_GetForwarder(config)), ENCAP_HICN,
+ fakeAddr);
+ addressDestroy(&fakeAddr);
+
+ if (listenerOps == NULL) {
+ printf("the main listener does not exists\n");
+ return false;
+ }
+
+ struct sockaddr_in6 puntingAddr;
+ bool res = addressGetInet6(puntingGetAddress(punting), &puntingAddr);
+ if (!res) {
+ printf("unable to read the punting address\n");
+ return false;
+ }
+
+ char prefix[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, &(puntingAddr.sin6_addr), prefix, INET6_ADDRSTRLEN);
+
+ char len[5];
+ sprintf(len, "%d", puntingPrefixLen(punting));
+
+ char *prefixStr =
+ malloc(strlen(prefix) + strlen(len) + 2); //+1 for the zero-terminator
+ if (prefixStr == NULL) {
+ printf("error while create the prefix string\n");
+ return false;
+ }
+ strcpy(prefixStr, prefix);
+ strcat(prefixStr, "/");
+ strcat(prefixStr, len);
+
+ res = hicnListener_Punting(listenerOps, prefixStr);
+ if (!res) {
+ printf("error while adding the punting rule\n");
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+//============= LIGHT COMMAN ===============
+
+static bool _addEther(Configuration *config, add_listener_command *control,
+ unsigned ingressId) {
+ // Not implemented
+ return false;
+}
+
+static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
+ uint16_t *port) {
+ bool success = false;
+
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = *port;
+ addr.sin_addr.s_addr = *addr4;
+
+ ListenerOps *ops = tcpListener_CreateInet(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add TCP listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4,
+ uint16_t *port) {
+ bool success = false;
+
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = *port;
+ addr.sin_addr.s_addr = *addr4;
+
+ ListenerOps *ops = udpListener_CreateInet(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add UDP listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder,
+ ipv6_addr_t *addr6, uint16_t *port,
+ uint32_t scopeId) {
+ bool success = false;
+
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = *port;
+ addr.sin6_addr = *addr6;
+ addr.sin6_scope_id = scopeId;
+
+ ListenerOps *ops = tcpListener_CreateInet6(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add TCP6 listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder,
+ ipv6_addr_t *addr6, uint16_t *port) {
+ bool success = false;
+
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = *port;
+ addr.sin6_addr = *addr6;
+ addr.sin6_scope_id = 0;
+
+ ListenerOps *ops = udpListener_CreateInet6(forwarder, addr);
+ if (ops) {
+ success = listenerSet_Add(forwarder_GetListenerSet(forwarder), ops);
+ parcAssertTrue(success, "Failed to add UDP6 listener on %s to ListenerSet",
+ addressToString(ops->getListenAddress(ops)));
+ }
+ return success;
+}
+
+bool _addHicn(Configuration *config, add_listener_command *control,
+ unsigned ingressId) {
+ bool success = false;
+ const char *symbolic = control->symbolic;
+ Address *localAddress = NULL;
+
+ switch (control->addressType) {
+ case ADDR_INET: {
+ localAddress =
+ utils_AddressFromInet(&control->address.ipv4, &control->port);
+ success = _setupHIcnListenerOnInet4(configuration_GetForwarder(config),
+ symbolic, localAddress);
+ break;
+ }
+
+ case ADDR_INET6: {
+ localAddress =
+ utils_AddressFromInet6(&control->address.ipv6, &control->port);
+ success = _setupHIcnListenerOnInet6(configuration_GetForwarder(config),
+ symbolic, localAddress);
+ break;
+ }
+
+ default:
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Warning)) {
+ logger_Log(configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Warning, __func__,
+ "Unsupported address type for HICN (ingress id %u): "
+ "must be either IPV4 or IPV6",
+ ingressId);
+ }
+ break;
+ }
+
+ if (success == true && localAddress != NULL) {
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Info)) {
+ logger_Log(configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Info, __func__,
+ "Setup hicn listener on address %s",
+ addressToString(localAddress));
+ }
+ }
+
+ addressDestroy(&localAddress);
+
+ return success;
+}
+
+bool _addIP(Configuration *config, add_listener_command *control,
+ unsigned ingressId) {
+ bool success = false;
+
+ switch (control->addressType) {
+ case ADDR_INET: {
+ if (control->connectionType == UDP_CONN) {
+ success =
+ _setupUdpListenerOnInet(configuration_GetForwarder(config),
+ &control->address.ipv4, &control->port);
+ } else if (control->connectionType == TCP_CONN) {
+ success =
+ _setupTcpListenerOnInet(configuration_GetForwarder(config),
+ &control->address.ipv4, &control->port);
+ }
+ break;
+ }
+
+ case ADDR_INET6: {
+ if (control->connectionType == UDP_CONN) {
+ success = _setupUdpListenerOnInet6Light(
+ configuration_GetForwarder(config), &control->address.ipv6,
+ &control->port);
+ } else if (control->connectionType == TCP_CONN) {
+ success = _setupTcpListenerOnInet6Light(
+ configuration_GetForwarder(config), &control->address.ipv6,
+ &control->port, 0);
+ }
+ break;
+ }
+
+ default:
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Warning)) {
+ char *addrStr = utils_CommandAddressToString(
+ control->addressType, &control->address, &control->port);
+ logger_Log(
+ configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Warning, __func__,
+ "Unsupported address type for IP encapsulation ingress id %u: %s",
+ ingressId, addrStr);
+ parcMemory_Deallocate((void **)&addrStr);
+ }
+ break;
+ }
+
+ if (success) {
+ if (logger_IsLoggable(configuration_GetLogger(config),
+ LoggerFacility_Config, PARCLogLevel_Info)) {
+ char *addrStr = utils_CommandAddressToString(
+ control->addressType, &control->address, &control->port);
+ logger_Log(configuration_GetLogger(config), LoggerFacility_Config,
+ PARCLogLevel_Info, __func__, "Setup listener on address %s",
+ addrStr);
+ parcMemory_Deallocate((void **)&addrStr);
+ }
+ }
+
+ return success;
+}
+
+struct iovec *configurationListeners_Add(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId) {
+ header_control_message *header = request[0].iov_base;
+ add_listener_command *control = request[1].iov_base;
+
+ bool success = false;
+
+ if (control->listenerMode == ETHER_MODE) {
+ parcTrapNotImplemented("Add Ethernet Listener is not supported");
+ success = _addEther(config, control, ingressId);
+ // it is a failure
+ } else if (control->listenerMode == IP_MODE) {
+ success = _addIP(config, control, ingressId);
+ } else if (control->listenerMode == HICN_MODE) {
+ success = _addHicn(config, control, ingressId);
+ } else {
+ Logger *logger = configuration_GetLogger(config);
+ if (logger_IsLoggable(logger, LoggerFacility_Config,
+ PARCLogLevel_Warning)) {
+ logger_Log(logger, LoggerFacility_Config, PARCLogLevel_Warning, __func__,
+ "Unsupported encapsulation mode (ingress id %u)", ingressId);
+ }
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_listener_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(add_listener_command));
+ }
+
+ return response;
+}
+
+struct iovec *configurationListeners_AddPunting(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId) {
+ header_control_message *header = request[0].iov_base;
+ add_punting_command *control = request[1].iov_base;
+
+ const char *symbolicOrConnid = control->symbolicOrConnid;
+ uint32_t len = control->len;
+ in_port_t port = htons(1234);
+ bool success = false;
+
+ if (control->addressType == ADDR_INET) {
+ Address *address = utils_AddressFromInet(&control->address.ipv4, &port);
+ Punting *punting = puntingCreate(symbolicOrConnid, address, len);
+ success = _AddPuntingInet(config, punting, ingressId);
+ addressDestroy(&address);
+ } else if (control->addressType == ADDR_INET6) {
+ Address *address = utils_AddressFromInet6(&control->address.ipv6, &port);
+ Punting *punting = puntingCreate(symbolicOrConnid, address, len);
+ success = _AddPuntingInet6(config, punting, ingressId);
+ addressDestroy(&address);
+ } else {
+ printf("Invalid IP type.\n"); // will generate a Nack
+ return utils_CreateNack(header, control, sizeof(add_punting_command));
+ }
+
+ // generate ACK/NACK
+ struct iovec *response;
+ if (success) { // ACK
+ response = utils_CreateAck(header, control, sizeof(add_punting_command));
+ } else { // NACK
+ response = utils_CreateNack(header, control, sizeof(add_punting_command));
+ }
+
+ return response;
+}
+
+//=========================== INITIAL LISTENERS ====================
+
+static void _setupListenersOnAddress(Forwarder *forwarder,
+ const Address *address, uint16_t port,
+ const char *interfaceName) {
+ address_type type = addressGetType(address);
+ switch (type) {
+ case ADDR_INET: {
+ struct sockaddr_in tmp;
+ addressGetInet(address, &tmp);
+ _setupTcpListenerOnInet(forwarder, &tmp.sin_addr.s_addr, &port);
+ break;
+ }
+
+ case ADDR_INET6: {
+ struct sockaddr_in6 tmp;
+ addressGetInet6(address, &tmp);
+ _setupTcpListenerOnInet6Light(forwarder, &tmp.sin6_addr, &port,
+ tmp.sin6_scope_id);
+ break;
+ }
+
+ case ADDR_LINK:
+ // not used
+ break;
+
+ default:
+ // dont' know how to handle this, so no listeners
+ break;
+ }
+}
+
+void configurationListeners_SetupAll(const Configuration *config, uint16_t port,
+ const char *localPath) {
+ Forwarder *forwarder = configuration_GetForwarder(config);
+ InterfaceSet *set = system_Interfaces(forwarder);
+
+ size_t interfaceSetLen = interfaceSetLength(set);
+ for (size_t i = 0; i < interfaceSetLen; i++) {
+ Interface *iface = interfaceSetGetByOrdinalIndex(set, i);
+
+ const AddressList *addresses = interfaceGetAddresses(iface);
+ size_t addressListLen = addressListLength(addresses);
+
+ for (size_t j = 0; j < addressListLen; j++) {
+ const Address *address = addressListGetItem(addresses, j);
+
+ // Do not start on link address
+ if (addressGetType(address) != ADDR_LINK) {
+ _setupListenersOnAddress(forwarder, address, htons(port),
+ interfaceGetName(iface));
+ }
+ }
+ }
+
+ // if (localPath != NULL) {
+ // _setupLocalListener(forwarder, localPath);
+ //}
+
+ interfaceSetDestroy(&set);
+}
diff --git a/hicn-light/src/config/configurationListeners.h b/hicn-light/src/config/configurationListeners.h
new file mode 100755
index 000000000..7332b0c64
--- /dev/null
+++ b/hicn-light/src/config/configurationListeners.h
@@ -0,0 +1,62 @@
+/*
+ * 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 configurationListeners.h
+ * @brief Configuration routines related to Listeners
+ *
+ * Adding and removing listeners.
+ *
+ */
+
+#ifndef configurationListeners_h
+#define configurationListeners_h
+
+#include <src/config/configuration.h>
+#include <src/core/forwarder.h>
+
+#include <src/utils/address.h>
+
+/**
+ * Setup udp, tcp, and local listeners
+ *
+ * Will bind to all available IP protocols on the given port.
+ * Does not add Ethernet listeners.
+ *
+ * @param port is the UPD and TCP port to use
+ * @param localPath is the AF_UNIX path to use, if NULL no AF_UNIX listener is
+ * setup
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void configurationListeners_SetupAll(const Configuration *config, uint16_t port,
+ const char *localPath);
+
+bool configurationListeners_Remove(const Configuration *config);
+
+// light functions
+
+struct iovec *configurationListeners_Add(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId);
+
+struct iovec *configurationListeners_AddPunting(Configuration *config,
+ struct iovec *request,
+ unsigned ingressId);
+
+#endif /* defined(configurationListeners_h) */
diff --git a/hicn-light/src/config/controlAdd.c b/hicn-light/src/config/controlAdd.c
new file mode 100755
index 000000000..72f8e9759
--- /dev/null
+++ b/hicn-light/src/config/controlAdd.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <src/config.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlAdd.h>
+#include <src/config/controlAddConnection.h>
+#include <src/config/controlAddListener.h>
+#include <src/config/controlAddPunting.h>
+#include <src/config/controlAddRoute.h>
+
+// ===================================================
+
+static void _controlAdd_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlAdd_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAdd_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+// ===================================================
+
+static const char *command_add = "add";
+static const char *help_command_add = "help add";
+
+CommandOps *webControlAdd_Create(ControlState *state) {
+ return commandOps_Create(state, command_add, _controlAdd_Init,
+ _controlAdd_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAdd_CreateHelp(ControlState *state) {
+ return commandOps_Create(state, help_command_add, NULL,
+ _controlAdd_HelpExecute, commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandReturn _controlAdd_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ CommandOps *ops_add_connection = controlAddConnection_Create(NULL);
+ CommandOps *ops_add_route = controlAddRoute_Create(NULL);
+ CommandOps *ops_add_punting = controlAddPunting_Create(NULL);
+ CommandOps *ops_add_listener = controlAddListener_Create(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_add_connection->command);
+ printf(" %s\n", ops_add_route->command);
+ printf(" %s\n", ops_add_punting->command);
+ printf(" %s\n", ops_add_listener->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_add_connection);
+ commandOps_Destroy(&ops_add_route);
+ commandOps_Destroy(&ops_add_punting);
+ commandOps_Destroy(&ops_add_listener);
+ return CommandReturn_Success;
+}
+
+static void _controlAdd_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlAddListener_HelpCreate(state));
+ controlState_RegisterCommand(state, controlAddListener_Create(state));
+ controlState_RegisterCommand(state, controlAddConnection_HelpCreate(state));
+ controlState_RegisterCommand(state, controlAddRoute_HelpCreate(state));
+ controlState_RegisterCommand(state, controlAddConnection_Create(state));
+ controlState_RegisterCommand(state, controlAddRoute_Create(state));
+ controlState_RegisterCommand(state, controlAddPunting_Create(state));
+ controlState_RegisterCommand(state, controlAddPunting_HelpCreate(state));
+}
+
+static CommandReturn _controlAdd_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args) {
+ return _controlAdd_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlAdd.h b/hicn-light/src/config/controlAdd.h
new file mode 100755
index 000000000..e1955f200
--- /dev/null
+++ b/hicn-light/src/config/controlAdd.h
@@ -0,0 +1,32 @@
+/*
+ * 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 control_Add.h
+ * @brief Command-line "add" node
+ *
+ * Implements the "add" node of the CLI tree
+ *
+ *
+ */
+
+#ifndef control_Add_h
+#define control_Add_h
+
+#include <src/config/controlState.h>
+
+CommandOps *webControlAdd_Create(ControlState *state);
+CommandOps *controlAdd_CreateHelp(ControlState *state);
+#endif // control_Add_h
diff --git a/hicn-light/src/config/controlAddConnection.c b/hicn-light/src/config/controlAddConnection.c
new file mode 100755
index 000000000..a0a966ddf
--- /dev/null
+++ b/hicn-light/src/config/controlAddConnection.c
@@ -0,0 +1,390 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <parc/assert/parc_Assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlAddConnection.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+// ===================================================
+
+static void _controlAddConnection_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlAddConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static CommandReturn _controlAddConnection_HIcnHelpExecute(
+ CommandParser *parser, CommandOps *ops, PARCList *args);
+static CommandReturn _controlAddConnection_HIcnExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static CommandReturn _controlAddConnection_UdpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddConnection_UdpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static CommandReturn _controlAddConnection_TcpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddConnection_TcpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandAddConnection = "add connection";
+static const char *_commandAddConnectionHIcn = "add connection hicn";
+static const char *_commandAddConnectionUdp = "add connection udp";
+static const char *_commandAddConnectionTcp = "add connection tcp";
+static const char *_commandAddConnectionHelp = "help add connection";
+static const char *_commandAddConnectionHIcnHelp = "help add connection hicn";
+static const char *_commandAddConnectionUdpHelp = "help add connection udp";
+static const char *_commandAddConnectionTcpHelp = "help add connection tcp";
+
+// ===================================================
+
+CommandOps *controlAddConnection_Create(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnection,
+ _controlAddConnection_Init,
+ _controlAddConnection_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddConnection_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionHelp, NULL,
+ _controlAddConnection_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandOps *_controlAddConnection_HIcnCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionHIcn, NULL,
+ _controlAddConnection_HIcnExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_UdpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionUdp, NULL,
+ _controlAddConnection_UdpExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_TcpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionTcp, NULL,
+ _controlAddConnection_TcpExecute,
+ commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandOps *_controlAddConnection_HIcnHelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionHIcnHelp, NULL,
+ _controlAddConnection_HIcnHelpExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_UdpHelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionUdpHelp, NULL,
+ _controlAddConnection_UdpHelpExecute,
+ commandOps_Destroy);
+}
+
+static CommandOps *_controlAddConnection_TcpHelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddConnectionTcpHelp, NULL,
+ _controlAddConnection_TcpHelpExecute,
+ commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandReturn _controlAddConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("Available commands:\n");
+ printf(" %s\n", _commandAddConnectionHIcn);
+ printf(" %s\n", _commandAddConnectionUdp);
+ printf(" %s\n", _commandAddConnectionTcp);
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static void _controlAddConnection_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state,
+ _controlAddConnection_HIcnHelpCreate(state));
+ controlState_RegisterCommand(state,
+ _controlAddConnection_UdpHelpCreate(state));
+ controlState_RegisterCommand(state,
+ _controlAddConnection_TcpHelpCreate(state));
+
+ controlState_RegisterCommand(state, _controlAddConnection_HIcnCreate(state));
+ controlState_RegisterCommand(state, _controlAddConnection_UdpCreate(state));
+ controlState_RegisterCommand(state, _controlAddConnection_TcpCreate(state));
+}
+
+static CommandReturn _controlAddConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ return _controlAddConnection_HelpExecute(parser, ops, args);
+}
+
+// ===================================================
+// functions general to all connection types
+
+/**
+ * Create a tunnel in the forwarder based on the addresses
+ *
+ * Caller retains ownership of memory.
+ * The symbolic name will be used to refer to this connection. It must be unqiue
+ * otherwise the forwarder will reject this commend.
+ *
+ * @param [in] parser An allocated CommandParser
+ * @param [in] ops Allocated CommandOps (needed to extract ControlState)
+ * @param [in] localAddress the local IP and port. The port may be the wildcard
+ * value.
+ * @param [in] remoteAddress The remote IP and port (both must be specified)
+ * @param [in] tunnelType The tunneling protocol
+ * @param [in] symbolic The symbolic name for the connection (must be unique)
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * {
+ * struct sockaddr_in *anyAddress = parcNetwork_SockInet4AddressAny();
+ * struct sockaddr_in *remote =
+ * parcNetwork_SockInet4Address("192.168.1.2", 9695);
+ *
+ * Address *localAddress = addressCreateFromInet(anyAddress);
+ * Address *remoteAddress = addressCreateFromInet(remote);
+ *
+ * control_CreateTunnel(state, localAddress, remoteAddress, IPTUN_TCP,
+ * "conn7");
+ *
+ * addressDestroy(&localAddress);
+ * addressDestroy(&remoteAddress);
+ * parcMemory_Deallocate((void **)&remote);
+ * parcMemory_Deallocate((void **)&anyAddress);
+ * }
+ * @endcode
+ */
+
+static CommandReturn _controlAddConnection_CreateTunnel(
+ CommandParser *parser, CommandOps *ops, const char *local_ip,
+ const char *local_port, const char *remote_ip, const char *remote_port,
+ connection_type tunnelType, const char *symbolic) {
+ ControlState *state = ops->closure;
+ // a request like this always has an interface index of 0 [FIELD REMOVED]
+ // unsigned int interfaceIndex = 0;
+
+ // allocate command payload
+ add_connection_command *addConnectionCommand =
+ parcMemory_AllocateAndClear(sizeof(add_connection_command));
+
+ // check and set IP addresses
+ if (inet_pton(AF_INET, remote_ip, &addConnectionCommand->remoteIp.ipv4) ==
+ 1 &&
+ inet_pton(AF_INET, local_ip, &addConnectionCommand->localIp.ipv4) == 1) {
+ addConnectionCommand->ipType = ADDR_INET;
+
+ } else if (inet_pton(AF_INET6, remote_ip,
+ &addConnectionCommand->remoteIp.ipv6) == 1 &&
+ inet_pton(AF_INET6, local_ip,
+ &addConnectionCommand->localIp.ipv6) == 1) {
+ addConnectionCommand->ipType = ADDR_INET6;
+
+ } else {
+ printf("Error: local address %s not same type as remote address %s\n",
+ local_ip, remote_ip);
+ parcMemory_Deallocate(&addConnectionCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addConnectionCommand->connectionType = tunnelType;
+ strcpy(addConnectionCommand->symbolic, symbolic);
+ addConnectionCommand->remotePort = htons((uint16_t)atoi(remote_port));
+ addConnectionCommand->localPort = htons((uint16_t)atoi(local_port));
+
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, ADD_CONNECTION, addConnectionCommand,
+ sizeof(add_connection_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_IpHelp(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args,
+ const char *protocol) {
+ printf("add connection hicn <symbolic> <remote_ip> <local_ip>\n");
+ printf(
+ "add connection udp <symbolic> <remote_ip> <port> <local_ip> <port>\n");
+ printf(
+ " <symbolic> : symbolic name, e.g. 'conn1' (must be "
+ "unique, start with alpha)\n");
+ printf(
+ " <remote_ip> : the IPv4 or IPv6 or hostname of the remote system\n");
+ printf(" <local_ip> : optional local IP address to bind to\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_HIcnHelpExecute(
+ CommandParser *parser, CommandOps *ops, PARCList *args) {
+ _controlAddConnection_IpHelp(parser, ops, args, "hicn");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_HIcnExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ static const int _indexSymbolic = 3;
+ static const int _indexRemAddr = 4;
+ static const int _indexLocAddr = 5;
+
+ if (parcList_Size(args) != 6) {
+ _controlAddConnection_HIcnHelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Invalid symbolic name. Must begin with alpha and contain only "
+ "alphanum.\n");
+ return CommandReturn_Failure;
+ }
+
+ char *remote_ip = parcList_GetAtIndex(args, _indexRemAddr);
+ char *local_ip = parcList_GetAtIndex(args, _indexLocAddr);
+ char *port = "1234"; // this is a random port number that will be ignored
+
+ return _controlAddConnection_CreateTunnel(
+ parser, ops, local_ip, port, remote_ip, port, HICN_CONN, symbolic);
+}
+
+static CommandReturn _controlAddConnection_UdpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ _controlAddConnection_IpHelp(parser, ops, args, "udp");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_UdpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ static const int _indexSymbolic = 3;
+ static const int _indexRemAddr = 4;
+ static const int _indexRemPort = 5;
+ static const int _indexLocAddr = 6;
+ static const int _indexLocPort = 7;
+
+ if (parcList_Size(args) != 8) {
+ _controlAddConnection_UdpHelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Invalid symbolic name. Must begin with alpha and contain only "
+ "alphanum.\n");
+ return CommandReturn_Failure;
+ }
+
+ char *remote_ip = parcList_GetAtIndex(args, _indexRemAddr);
+ char *local_ip = parcList_GetAtIndex(args, _indexLocAddr);
+
+ char *remote_port = parcList_GetAtIndex(args, _indexRemPort);
+ char *local_port = parcList_GetAtIndex(args, _indexLocPort);
+
+ return _controlAddConnection_CreateTunnel(parser, ops, local_ip, local_port,
+ remote_ip, remote_port, UDP_CONN,
+ symbolic);
+}
+
+static CommandReturn _controlAddConnection_TcpHelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ _controlAddConnection_IpHelp(parser, ops, args, "tcp");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddConnection_TcpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ static const int _indexSymbolic = 3;
+ static const int _indexRemAddr = 4;
+ static const int _indexRemPort = 5;
+ static const int _indexLocAddr = 6;
+ static const int _indexLocPort = 7;
+
+ if (parcList_Size(args) != 8) {
+ _controlAddConnection_UdpHelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Invalid symbolic name. Must begin with alpha and contain only "
+ "alphanum.\n");
+ return CommandReturn_Failure;
+ }
+
+ char *remote_ip = parcList_GetAtIndex(args, _indexRemAddr);
+ char *local_ip = parcList_GetAtIndex(args, _indexLocAddr);
+
+ char *remote_port = parcList_GetAtIndex(args, _indexRemPort);
+ char *local_port = parcList_GetAtIndex(args, _indexLocPort);
+
+ return _controlAddConnection_CreateTunnel(parser, ops, local_ip, local_port,
+ remote_ip, remote_port, TCP_CONN,
+ symbolic);
+}
diff --git a/hicn-light/src/config/controlAddConnection.h b/hicn-light/src/config/controlAddConnection.h
new file mode 100755
index 000000000..788306989
--- /dev/null
+++ b/hicn-light/src/config/controlAddConnection.h
@@ -0,0 +1,31 @@
+/*
+ * 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 control_AddConnection.h
+ * @brief Command-line "add connection" node
+ *
+ * Implements the "add connection" node of the CLI tree
+ *
+ *
+ */
+
+#ifndef controlAddConnection_h
+#define controlAddConnection_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddConnection_Create(ControlState *state);
+CommandOps *controlAddConnection_HelpCreate(ControlState *state);
+#endif // controlAddConnection_h
diff --git a/hicn-light/src/config/controlAddListener.c b/hicn-light/src/config/controlAddListener.c
new file mode 100755
index 000000000..8f687c3a6
--- /dev/null
+++ b/hicn-light/src/config/controlAddListener.c
@@ -0,0 +1,178 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlAddListener.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlAddListener_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *command_add_listener = "add listener";
+static const char *command_help_add_listener = "help add listener";
+
+CommandOps *controlAddListener_Create(ControlState *state) {
+ return commandOps_Create(state, command_add_listener, NULL,
+ _controlAddListener_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddListener_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, command_help_add_listener, NULL,
+ _controlAddListener_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static const int _indexProtocol = 2;
+static const int _indexSymbolic = 3;
+static const int _indexAddress = 4;
+static const int _indexPort = 5;
+
+static CommandReturn _controlAddListener_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("commands:\n");
+ printf(" add listener hicn <symbolic> <localAddress> \n");
+ printf(" add listener udp <symbolic> <localAddress> <port> \n");
+ printf(" add listener tcp <symbolic> <localAddress> <port> \n");
+ printf("\n");
+ printf(
+ " symbolic: User defined name for listener, must start with "
+ "alpha and be alphanum\n");
+ printf(" protocol: hicn | udp\n");
+ printf(
+ " localAddress: IPv4 or IPv6 address (or prefix protocol = hicn) "
+ "assigend to the local interface\n");
+ printf(" port: Udp port\n");
+ printf("\n");
+ printf("Notes:\n");
+ printf(" The symblic name must be unique or the source will reject it.\n");
+ printf(
+ " If protocol = hinc: the address 0::0 indicates the main listern, "
+ "for which we can set punting rules.\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _CreateListener(CommandParser *parser, CommandOps *ops,
+ const char *symbolic, const char *addr,
+ const char *port, listener_mode mode,
+ connection_type type) {
+ ControlState *state = ops->closure;
+
+ // allocate command payload
+ add_listener_command *addListenerCommand =
+ parcMemory_AllocateAndClear(sizeof(add_listener_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &addListenerCommand->address.ipv4) == 1) {
+ addListenerCommand->addressType = ADDR_INET;
+
+ } else if (inet_pton(AF_INET6, addr, &addListenerCommand->address.ipv6) ==
+ 1) {
+ addListenerCommand->addressType = ADDR_INET6;
+
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&addListenerCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addListenerCommand->listenerMode = mode;
+ addListenerCommand->connectionType = type;
+ addListenerCommand->port = htons((uint16_t)atoi(port));
+ strcpy(addListenerCommand->symbolic, symbolic);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, ADD_LISTENER, addListenerCommand, sizeof(add_listener_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddListener_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 5 && parcList_Size(args) != 6) {
+ _controlAddListener_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ CommandReturn result = CommandReturn_Failure;
+
+ const char *symbolic = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolic)) {
+ printf(
+ "Error: symbolic name must begin with an alpha and be alphanum "
+ "after\n");
+ return result;
+ }
+
+ const char *host = parcList_GetAtIndex(args, _indexAddress);
+ const char *protocol = parcList_GetAtIndex(args, _indexProtocol);
+
+ if ((strcasecmp("hicn", protocol) == 0)) {
+ const char *port =
+ "1234"; // this is a random port number that will be ignored
+
+ // here we discard the prefix len if it exists, since we don't use it in
+ // code but we let libhicn to find the right ip address.
+ return _CreateListener(parser, ops, symbolic, host, port, HICN_MODE,
+ HICN_CONN);
+ }
+
+ const char *port = parcList_GetAtIndex(args, _indexPort);
+
+ if ((strcasecmp("udp", protocol) == 0)) {
+ return _CreateListener(parser, ops, symbolic, host, port, IP_MODE,
+ UDP_CONN);
+ } else if ((strcasecmp("tcp", protocol) == 0)) {
+ return _CreateListener(parser, ops, symbolic, host, port, IP_MODE,
+ TCP_CONN);
+ } else {
+ _controlAddListener_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ if (result == CommandReturn_Failure) printf("creation failed\n");
+
+ return result;
+}
diff --git a/hicn-light/src/config/controlAddListener.h b/hicn-light/src/config/controlAddListener.h
new file mode 100755
index 000000000..d3fc55aaf
--- /dev/null
+++ b/hicn-light/src/config/controlAddListener.h
@@ -0,0 +1,30 @@
+/*
+ * 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 control_AddListener.h
+ * @brief Add a listener to an interface
+ *
+ * <#Detailed Description#>
+ *
+ */
+
+#ifndef Control_AddListener_h
+#define Control_AddListener_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddListener_Create(ControlState *state);
+CommandOps *controlAddListener_HelpCreate(ControlState *state);
+#endif // Control_AddListener_h
diff --git a/hicn-light/src/config/controlAddPunting.c b/hicn-light/src/config/controlAddPunting.c
new file mode 100755
index 000000000..bd87e517c
--- /dev/null
+++ b/hicn-light/src/config/controlAddPunting.c
@@ -0,0 +1,154 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <src/utils/punting.h>
+
+#include <src/config/controlAddPunting.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlAddPunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlAddPunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandAddPunting = "add punting";
+static const char *_commandAddPuntingHelp = "help add punting";
+
+static const int _indexSymbolic = 2;
+static const int _indexPrefix = 3;
+
+CommandOps *controlAddPunting_Create(ControlState *state) {
+ return commandOps_Create(state, _commandAddPunting, NULL,
+ _controlAddPunting_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddPunting_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddPuntingHelp, NULL,
+ _controlAddPunting_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlAddPunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("add punting <symbolic> <prefix>\n");
+ printf(" <symbolic> : listener symbolic name\n");
+ printf(
+ " <address> : prefix to add as a punting rule. (example "
+ "1234::0/64)\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddPunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlAddPunting_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, _indexSymbolic);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\n"
+ "symbolic name must begin with an alpha followed by alphanum;\nconnid "
+ "must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, _indexPrefix);
+ char addr[strlen(prefixStr) + 1];
+
+ // separate address and len
+ char *slash;
+ uint32_t len = 0;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ add_punting_command *addPuntingCommand =
+ parcMemory_AllocateAndClear(sizeof(add_punting_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &addPuntingCommand->address.ipv4) == 1) {
+ if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&addPuntingCommand);
+ return CommandReturn_Failure;
+ }
+ addPuntingCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &addPuntingCommand->address.ipv6) == 1) {
+ if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&addPuntingCommand);
+ return CommandReturn_Failure;
+ }
+ addPuntingCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&addPuntingCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addPuntingCommand->len = len;
+ strcpy(addPuntingCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, ADD_PUNTING, addPuntingCommand, sizeof(add_punting_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlAddPunting.h b/hicn-light/src/config/controlAddPunting.h
new file mode 100755
index 000000000..e4d4aac7e
--- /dev/null
+++ b/hicn-light/src/config/controlAddPunting.h
@@ -0,0 +1,22 @@
+/*
+ * 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 controlAddPunting_h
+#define controlAddPunting_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddPunting_Create(ControlState *state);
+CommandOps *controlAddPunting_HelpCreate(ControlState *state);
+#endif
diff --git a/hicn-light/src/config/controlAddRoute.c b/hicn-light/src/config/controlAddRoute.c
new file mode 100755
index 000000000..c5ddab523
--- /dev/null
+++ b/hicn-light/src/config/controlAddRoute.c
@@ -0,0 +1,157 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlAddRoute.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlAddRoute_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlAddRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandAddRoute = "add route";
+static const char *_commandAddRouteHelp = "help add route";
+
+CommandOps *controlAddRoute_Create(ControlState *state) {
+ return commandOps_Create(state, _commandAddRoute, NULL,
+ _controlAddRoute_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlAddRoute_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandAddRouteHelp, NULL,
+ _controlAddRoute_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlAddRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("commands:\n");
+ printf(" add route <symbolic | connid> <prefix> <cost>\n");
+ printf("\n");
+ printf(" symbolic: The symbolic name for an exgress\n");
+ printf(
+ " connid: The egress connection id (see 'help list connections')\n");
+ printf(
+ " prefix: The hicn name as IPv4 or IPv6 address (e.g 1234::0/64)\n");
+ printf(" cost: positive integer representing cost\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlAddRoute_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 5) {
+ _controlAddRoute_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 2);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ unsigned cost = atoi(parcList_GetAtIndex(args, 4));
+
+ if (cost == 0) {
+ printf("ERROR: cost must be positive integer, got %u from '%s'\n", cost,
+ (char *)parcList_GetAtIndex(args, 4));
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, 3);
+ char addr[strlen(prefixStr) + 1];
+
+ // separate address and len
+ char *slash;
+ uint32_t len = 0;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ add_route_command *addRouteCommand =
+ parcMemory_AllocateAndClear(sizeof(add_route_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &addRouteCommand->address.ipv4) == 1) {
+ if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&addRouteCommand);
+ return CommandReturn_Failure;
+ }
+ addRouteCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &addRouteCommand->address.ipv6) == 1) {
+ if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&addRouteCommand);
+ return CommandReturn_Failure;
+ }
+ addRouteCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&addRouteCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ addRouteCommand->len = len;
+ addRouteCommand->cost = (uint16_t)cost;
+ strcpy(addRouteCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, ADD_ROUTE, addRouteCommand,
+ sizeof(add_route_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlAddRoute.h b/hicn-light/src/config/controlAddRoute.h
new file mode 100755
index 000000000..be0ad1368
--- /dev/null
+++ b/hicn-light/src/config/controlAddRoute.h
@@ -0,0 +1,30 @@
+/*
+ * 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 control_AddRoute.h
+ * @brief Add a static route
+ *
+ * Implements the "add route" node of the CLI tree
+ *
+ */
+
+#ifndef Control_AddRoute_h
+#define Control_AddRoute_h
+
+#include <src/config/controlState.h>
+CommandOps *controlAddRoute_Create(ControlState *state);
+CommandOps *controlAddRoute_HelpCreate(ControlState *state);
+#endif // Control_AddRoute_h
diff --git a/hicn-light/src/config/controlCache.c b/hicn-light/src/config/controlCache.c
new file mode 100755
index 000000000..d7afbfe7d
--- /dev/null
+++ b/hicn-light/src/config/controlCache.c
@@ -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.
+ */
+
+#include <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCache.h>
+#include <src/config/controlCacheClear.h>
+#include <src/config/controlCacheServe.h>
+#include <src/config/controlCacheStore.h>
+
+static void _controlCache_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlCache_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlCache_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandCache = "cache";
+static const char *_commandCacheHelp = "help cache";
+
+CommandOps *controlCache_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCache, _controlCache_Init,
+ _controlCache_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCache_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheHelp, NULL,
+ _controlCache_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlCache_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_cache_serve = controlCacheServe_HelpCreate(NULL);
+ CommandOps *ops_cache_store = controlCacheStore_HelpCreate(NULL);
+ CommandOps *ops_cache_clear = controlCacheClear_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_cache_serve->command);
+ printf(" %s\n", ops_cache_store->command);
+ printf(" %s\n", ops_cache_clear->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_cache_serve);
+ commandOps_Destroy(&ops_cache_store);
+ commandOps_Destroy(&ops_cache_clear);
+
+ return CommandReturn_Success;
+}
+
+static void _controlCache_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlCacheServe_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCacheStore_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCacheClear_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCacheServe_Create(state));
+ controlState_RegisterCommand(state, controlCacheStore_Create(state));
+ controlState_RegisterCommand(state, controlCacheClear_Create(state));
+}
+
+static CommandReturn _controlCache_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlCache_HelpExecute(parser, ops, args);
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlCache.h b/hicn-light/src/config/controlCache.h
new file mode 100755
index 000000000..a3614fce1
--- /dev/null
+++ b/hicn-light/src/config/controlCache.h
@@ -0,0 +1,22 @@
+/*
+ * 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 controlCache_h
+#define controlCache_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCache_Create(ControlState *state);
+CommandOps *controlCache_HelpCreate(ControlState *state);
+#endif // controlCache_h
diff --git a/hicn-light/src/config/controlCacheClear.c b/hicn-light/src/config/controlCacheClear.c
new file mode 100755
index 000000000..c5a4e9fde
--- /dev/null
+++ b/hicn-light/src/config/controlCacheClear.c
@@ -0,0 +1,84 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCacheClear.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlCacheClear_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlCacheClear_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandCacheClear = "cache clear";
+static const char *_commandCacheClearHelp = "help cache clear";
+
+// ====================================================
+
+CommandOps *controlCacheClear_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCacheClear, NULL,
+ _controlCacheClear_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCacheClear_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheClearHelp, NULL,
+ _controlCacheClear_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlCacheClear_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("cache clear\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlCacheClear_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlCacheClear_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, CACHE_CLEAR, NULL, 0);
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlCacheClear.h b/hicn-light/src/config/controlCacheClear.h
new file mode 100755
index 000000000..348ddba12
--- /dev/null
+++ b/hicn-light/src/config/controlCacheClear.h
@@ -0,0 +1,30 @@
+/*
+ * 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 controlCacheClear.h
+ * @brief Clear the cache
+ *
+ * Removes all the cached data form the local content store (if available)
+ *
+ */
+
+#ifndef Control_CacheClear_h
+#define Control_CacheClear_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCacheClear_Create(ControlState *state);
+CommandOps *controlCacheClear_HelpCreate(ControlState *state);
+#endif // Control_CacheClear_h
diff --git a/hicn-light/src/config/controlCacheServe.c b/hicn-light/src/config/controlCacheServe.c
new file mode 100755
index 000000000..85d598025
--- /dev/null
+++ b/hicn-light/src/config/controlCacheServe.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCacheServe.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlCacheServe_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlCacheServe_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandCacheServe = "cache serve";
+static const char *_commandCacheServeHelp = "help cache serve";
+
+// ====================================================
+
+CommandOps *controlCacheServe_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCacheServe, NULL,
+ _controlCacheServe_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCacheServe_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheServeHelp, NULL,
+ _controlCacheServe_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlCacheServe_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("cache serve [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlCacheServe_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlCacheServe_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlCacheServe_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ cache_serve_command *cacheServeCommand =
+ parcMemory_AllocateAndClear(sizeof(cache_serve_command));
+ if (active) {
+ cacheServeCommand->activate = ACTIVATE_ON;
+ } else {
+ cacheServeCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, CACHE_SERVE, cacheServeCommand, sizeof(cache_serve_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlCacheServe.h b/hicn-light/src/config/controlCacheServe.h
new file mode 100755
index 000000000..4bcec51f0
--- /dev/null
+++ b/hicn-light/src/config/controlCacheServe.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_CacheServe_h
+#define Control_CacheServe_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCacheServe_Create(ControlState *state);
+CommandOps *controlCacheServe_HelpCreate(ControlState *state);
+#endif // Control_CacheServe_h
diff --git a/hicn-light/src/config/controlCacheStore.c b/hicn-light/src/config/controlCacheStore.c
new file mode 100755
index 000000000..3bbb34386
--- /dev/null
+++ b/hicn-light/src/config/controlCacheStore.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlCacheStore.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlCacheStore_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlCacheStore_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandCacheStore = "cache store";
+static const char *_commandCacheStoreHelp = "help cache store";
+
+// ====================================================
+
+CommandOps *controlCacheStore_Create(ControlState *state) {
+ return commandOps_Create(state, _commandCacheStore, NULL,
+ _controlCacheStore_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlCacheStore_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandCacheStoreHelp, NULL,
+ _controlCacheStore_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlCacheStore_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("cache store [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlCacheStore_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlCacheStore_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlCacheStore_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ cache_store_command *cacheStoreCommand =
+ parcMemory_AllocateAndClear(sizeof(cache_store_command));
+ if (active) {
+ cacheStoreCommand->activate = ACTIVATE_ON;
+ } else {
+ cacheStoreCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, CACHE_STORE, cacheStoreCommand, sizeof(cache_store_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlCacheStore.h b/hicn-light/src/config/controlCacheStore.h
new file mode 100755
index 000000000..ef5aca504
--- /dev/null
+++ b/hicn-light/src/config/controlCacheStore.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_CacheStore_h
+#define Control_CacheStore_h
+
+#include <src/config/controlState.h>
+CommandOps *controlCacheStore_Create(ControlState *state);
+CommandOps *controlCacheStore_HelpCreate(ControlState *state);
+#endif // Control_CacheStore_h
diff --git a/hicn-light/src/config/controlList.c b/hicn-light/src/config/controlList.c
new file mode 100755
index 000000000..8afaa60dc
--- /dev/null
+++ b/hicn-light/src/config/controlList.c
@@ -0,0 +1,97 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlList.h>
+#include <src/config/controlListConnections.h>
+//#include <src/config/controlListInterfaces.h>
+#include <src/config/controlListListeners.h>
+#include <src/config/controlListRoutes.h>
+
+static void _controlList_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlList_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlList_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandList = "list";
+static const char *_commandListHelp = "help list";
+
+CommandOps *controlList_Create(ControlState *state) {
+ return commandOps_Create(state, _commandList, _controlList_Init,
+ _controlList_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlList_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListHelp, NULL,
+ _controlList_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlList_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ CommandOps *ops_list_connections = controlListConnections_HelpCreate(NULL);
+ // CommandOps *ops_list_interfaces = controlListInterfaces_HelpCreate(NULL);
+ CommandOps *ops_list_routes = controlListRoutes_HelpCreate(NULL);
+ CommandOps *ops_list_listeners = controlListListeners_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_list_connections->command);
+ // printf(" %s\n", ops_list_interfaces->command);
+ printf(" %s\n", ops_list_routes->command);
+ printf(" %s\n", ops_list_listeners->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_list_connections);
+ // commandOps_Destroy(&ops_list_interfaces);
+ commandOps_Destroy(&ops_list_routes);
+ commandOps_Destroy(&ops_list_listeners);
+
+ return CommandReturn_Success;
+}
+
+static void _controlList_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlListConnections_HelpCreate(state));
+ // controlState_RegisterCommand(state,
+ // controlListInterfaces_HelpCreate(state));
+ controlState_RegisterCommand(state, controlListListeners_HelpCreate(state));
+ controlState_RegisterCommand(state, controlListRoutes_HelpCreate(state));
+ controlState_RegisterCommand(state, controlListConnections_Create(state));
+ // controlState_RegisterCommand(state, controlListInterfaces_Create(state));
+ controlState_RegisterCommand(state, controlListRoutes_Create(state));
+ controlState_RegisterCommand(state, controlListListeners_Create(state));
+}
+
+static CommandReturn _controlList_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlList_HelpExecute(parser, ops, args);
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlList.h b/hicn-light/src/config/controlList.h
new file mode 100755
index 000000000..53197331f
--- /dev/null
+++ b/hicn-light/src/config/controlList.h
@@ -0,0 +1,30 @@
+/*
+ * 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 control_List.h
+ * @brief Root node for the "list" commands
+ *
+ * Implements the "list" node of the CLI tree.
+ *
+ */
+
+#ifndef controlList_h
+#define controlList_h
+
+#include <src/config/controlState.h>
+CommandOps *controlList_Create(ControlState *state);
+CommandOps *controlList_HelpCreate(ControlState *state);
+#endif // controlList_h
diff --git a/hicn-light/src/config/controlListConnections.c b/hicn-light/src/config/controlListConnections.c
new file mode 100755
index 000000000..474ddc45f
--- /dev/null
+++ b/hicn-light/src/config/controlListConnections.c
@@ -0,0 +1,160 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlListConnections.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlListConnections_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListConnections_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListConnections = "list connections";
+static const char *_commandListConnectionsHelp = "help list connections";
+const char *connTypeString[6] = {"GRE", "TCP", "UDP", "MCAST", "L2", "HICN"};
+const char *stateString[3] = {"UP", "DOWN", "UNKNOWN"};
+
+CommandOps *controlListConnections_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListConnections, NULL,
+ _controlListConnections_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListConnections_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListConnectionsHelp, NULL,
+ _controlListConnections_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListConnections_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("list connections: displays a 1-line summary of each connection\n");
+ printf("\n");
+ printf("The columns are:\n");
+ printf(" connection id : an integer index for the connection\n");
+ printf(" state : UP or DOWN\n");
+ printf(
+ " local address : the local network address associated with the "
+ "connection\n");
+ printf(
+ " remote address: the remote network address associated with the "
+ "connection\n");
+ printf(
+ " protocol : the network protocol (tcp, udp, gre, mcast, "
+ "ether)\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListConnections_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListConnections_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, LIST_CONNECTIONS, NULL, 0);
+ if (!response) { // get NULL pointer = FAILURE
+ return CommandReturn_Failure;
+ }
+
+ // Process/Print message
+ header_control_message *receivedHeader =
+ (header_control_message *)response[0].iov_base;
+ uint8_t *receivedPayload = (uint8_t *)response[1].iov_base;
+
+ char *sourceString = NULL;
+ char *destinationString = NULL;
+
+ // Allocate output to pass to the main function if the call is not interactive
+ char **commandOutputMain = NULL;
+ if (!controlState_IsInteractive(state) && receivedHeader->length > 0) {
+ commandOutputMain =
+ parcMemory_Allocate(sizeof(char *) * receivedHeader->length);
+ for (size_t j = 0; j < receivedHeader->length; j++) {
+ commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128);
+ }
+ }
+
+ // Process/Print payload
+ for (int i = 0; i < receivedHeader->length; i++) {
+ list_connections_command *listConnectionsCommand =
+ (list_connections_command *)(receivedPayload +
+ (i * sizeof(list_connections_command)));
+
+ sourceString = utils_CommandAddressToString(
+ listConnectionsCommand->connectionData.ipType,
+ &listConnectionsCommand->connectionData.localIp,
+ &listConnectionsCommand->connectionData.localPort);
+
+ destinationString = utils_CommandAddressToString(
+ listConnectionsCommand->connectionData.ipType,
+ &listConnectionsCommand->connectionData.remoteIp,
+ &listConnectionsCommand->connectionData.remotePort);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ parcBufferComposer_Format(
+ composer, "%5d %4s %s %s %s", listConnectionsCommand->connid,
+ stateString[listConnectionsCommand->state], sourceString,
+ destinationString,
+ connTypeString[listConnectionsCommand->connectionData.connectionType]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+
+ if (!controlState_IsInteractive(state)) {
+ strcpy(commandOutputMain[i], result);
+ }
+
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+ }
+
+ controlState_SetCommandOutput(state, commandOutputMain);
+
+ // DEALLOCATE
+ parcMemory_Deallocate((void **)&sourceString);
+ parcMemory_Deallocate((void **)&destinationString);
+ parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base
+ parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base
+ parcMemory_Deallocate(&response); // free iovec pointer
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListConnections.h b/hicn-light/src/config/controlListConnections.h
new file mode 100755
index 000000000..17422c963
--- /dev/null
+++ b/hicn-light/src/config/controlListConnections.h
@@ -0,0 +1,30 @@
+/*
+ * 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 control_ListConnections.h
+ * @brief List the current connections of hicn-light
+ *
+ * Implements the "list connections" node of the CLI tree
+ *
+ */
+
+#ifndef Control_ListConnections_h
+#define Control_ListConnections_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListConnections_Create(ControlState *state);
+CommandOps *controlListConnections_HelpCreate(ControlState *state);
+#endif // Control_ListConnections_h
diff --git a/hicn-light/src/config/controlListInterfaces.c b/hicn-light/src/config/controlListInterfaces.c
new file mode 100755
index 000000000..20338b553
--- /dev/null
+++ b/hicn-light/src/config/controlListInterfaces.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlListInterfaces.h>
+
+static CommandReturn _controlListInterfaces_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListInterfaces_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListInterfaces = "list interfaces";
+static const char *_commandListInterfacesHelp = "help list interfaces";
+
+// ====================================================
+
+CommandOps *controlListInterfaces_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListInterfaces, NULL,
+ _controlListInterfaces_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListInterfaces_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListInterfacesHelp, NULL,
+ _controlListInterfaces_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListInterfaces_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("list interfaces\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListInterfaces_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListInterfaces_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ //========================== NOT IMPLEMENTED
+ //===========================
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListInterfaces.h b/hicn-light/src/config/controlListInterfaces.h
new file mode 100755
index 000000000..0c0ca95cf
--- /dev/null
+++ b/hicn-light/src/config/controlListInterfaces.h
@@ -0,0 +1,31 @@
+/*
+ * 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 control_ListInterfaces.h
+ * @brief List the icn-light interfaces
+ *
+ * Implements the "list interfaces" and "help list interfaces" nodes of the
+ * command tree
+ *
+ */
+
+#ifndef Control_ListInterfaces_h
+#define Control_ListInterfaces_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListInterfaces_Create(ControlState *state);
+CommandOps *controlListInterfaces_HelpCreate(ControlState *state);
+#endif // Control_ListInterfaces_h
diff --git a/hicn-light/src/config/controlListListeners.c b/hicn-light/src/config/controlListListeners.c
new file mode 100755
index 000000000..a149051e2
--- /dev/null
+++ b/hicn-light/src/config/controlListListeners.c
@@ -0,0 +1,141 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+
+#include <src/config/controlListListeners.h>
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlListListeners_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListListeners_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListListeners = "list listeners";
+static const char *_commandListListenersHelp = "help list listeners";
+static const char *listenerType[5] = {"TCP", "UDP", "ETHER", "LOCAL", "HICN"};
+
+// ====================================================
+
+CommandOps *controlListListeners_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListListeners, NULL,
+ _controlListListeners_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListListeners_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListListenersHelp, NULL,
+ _controlListListeners_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListListeners_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("list listeners\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListListeners_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListListeners_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, LIST_LISTENERS, NULL, 0);
+ if (!response) { // get NULL pointer = FAILURE
+ return CommandReturn_Failure;
+ }
+
+ // Process/Print message
+ header_control_message *receivedHeader =
+ (header_control_message *)response[0].iov_base;
+ uint8_t *receivedPayload = (uint8_t *)response[1].iov_base;
+
+ // Allocate output to pass to the main function if the call is not interactive
+ char **commandOutputMain = NULL;
+ if (!controlState_IsInteractive(state) && receivedHeader->length > 0) {
+ commandOutputMain =
+ parcMemory_Allocate(sizeof(char *) * receivedHeader->length);
+ for (size_t j = 0; j < receivedHeader->length; j++) {
+ commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128);
+ }
+ }
+
+ char *addrString = NULL;
+ if (receivedHeader->length > 0) {
+ printf("%6.6s %50.70s %s\n", "iface", "address", "type");
+ } else {
+ printf(" --- No entry in the list \n");
+ }
+
+ for (int i = 0; i < receivedHeader->length; i++) {
+ list_listeners_command *listListenersCommand =
+ (list_listeners_command *)(receivedPayload +
+ (i * sizeof(list_listeners_command)));
+
+ addrString = utils_CommandAddressToString(listListenersCommand->addressType,
+ &listListenersCommand->address,
+ &listListenersCommand->port);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ parcBufferComposer_Format(composer, "%6u %50.70s %3s",
+ listListenersCommand->connid, addrString,
+ listenerType[listListenersCommand->encapType]);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+
+ if (!controlState_IsInteractive(state)) {
+ strcpy(commandOutputMain[i], result);
+ }
+
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+ }
+
+ controlState_SetCommandOutput(state, commandOutputMain);
+
+ // DEALLOCATE
+ parcMemory_Deallocate((void **)&addrString);
+ parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base
+ parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base
+ parcMemory_Deallocate(&response); // free iovec pointer
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListListeners.h b/hicn-light/src/config/controlListListeners.h
new file mode 100755
index 000000000..1f34eea56
--- /dev/null
+++ b/hicn-light/src/config/controlListListeners.h
@@ -0,0 +1,31 @@
+/*
+ * 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 control_ListListeners.h
+ * @brief List the icn-light listeners
+ *
+ * Implements the "list listeners" and "help list listeners" nodes of the
+ * command tree
+ *
+ */
+
+#ifndef Control_ListListeners_h
+#define Control_ListListeners_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListListeners_Create(ControlState *state);
+CommandOps *controlListListeners_HelpCreate(ControlState *state);
+#endif // Control_ListListeners_h
diff --git a/hicn-light/src/config/controlListRoutes.c b/hicn-light/src/config/controlListRoutes.c
new file mode 100755
index 000000000..4a21b5ef4
--- /dev/null
+++ b/hicn-light/src/config/controlListRoutes.c
@@ -0,0 +1,154 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Time.h>
+
+#include <src/config/controlListRoutes.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlListRoutes_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlListRoutes_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandListRoutes = "list routes";
+static const char *_commandListRoutesHelp = "help list routes";
+
+// ====================================================
+
+CommandOps *controlListRoutes_Create(ControlState *state) {
+ return commandOps_Create(state, _commandListRoutes, NULL,
+ _controlListRoutes_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlListRoutes_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandListRoutesHelp, NULL,
+ _controlListRoutes_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlListRoutes_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("command: list routes\n");
+ printf("\n");
+ printf(
+ "This command will fetch the prefix routing table. For each route, it "
+ "will list:\n");
+ printf(" iface: interface\n");
+ printf(
+ " protocol: the routing protocol, such as STATIC, CONNECTED, etc.\n");
+ printf(
+ " type: LMP or EXACT (longest matching prefix or exact match)\n");
+ printf(" cost: The route cost, lower being preferred\n");
+ printf(" next: List of next hops by interface id\n");
+ printf(" prefix: name prefix\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlListRoutes_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlListRoutes_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, LIST_ROUTES, NULL, 0);
+ if (!response) { // get NULL pointer = FAILURE
+ return CommandReturn_Failure;
+ }
+
+ // Process/Print message
+ header_control_message *receivedHeader =
+ (header_control_message *)response[0].iov_base;
+ uint8_t *receivedPayload = (uint8_t *)response[1].iov_base;
+
+ // Allocate output to pass to the main function if the call is not interactive
+ char **commandOutputMain = NULL;
+ if (!controlState_IsInteractive(state) && receivedHeader->length > 0) {
+ commandOutputMain =
+ parcMemory_Allocate(sizeof(char *) * receivedHeader->length);
+ for (size_t j = 0; j < receivedHeader->length; j++) {
+ commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128);
+ }
+ }
+
+ char *addrString = NULL;
+ in_port_t port = htons(1234); // this is a random port number that is ignored
+
+ if (receivedHeader->length > 0) {
+ printf("%6.6s %8.8s %70.70s %s\n", "iface", "cost", "prefix", "len");
+ } else {
+ printf(" --- No entry in the list \n");
+ }
+
+ for (int i = 0; i < receivedHeader->length; i++) {
+ list_routes_command *listRoutesCommand =
+ (list_routes_command *)(receivedPayload +
+ (i * sizeof(list_routes_command)));
+
+ addrString = utils_CommandAddressToString(
+ listRoutesCommand->addressType, &listRoutesCommand->address, &port);
+
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ parcBufferComposer_Format(
+ composer, "%6u %8u %70.70s %3d", listRoutesCommand->connid,
+ listRoutesCommand->cost, addrString, listRoutesCommand->len);
+
+ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
+ char *result = parcBuffer_ToString(tempBuffer);
+ parcBuffer_Release(&tempBuffer);
+
+ if (!controlState_IsInteractive(state)) {
+ strcpy(commandOutputMain[i], result);
+ }
+
+ puts(result);
+ parcMemory_Deallocate((void **)&result);
+ parcBufferComposer_Release(&composer);
+ }
+
+ controlState_SetCommandOutput(state, commandOutputMain);
+
+ // DEALLOCATE
+ parcMemory_Deallocate((void **)&addrString);
+ parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base
+ parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base
+ parcMemory_Deallocate(&response); // free iovec pointer
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlListRoutes.h b/hicn-light/src/config/controlListRoutes.h
new file mode 100755
index 000000000..018c88ab0
--- /dev/null
+++ b/hicn-light/src/config/controlListRoutes.h
@@ -0,0 +1,29 @@
+/*
+ * 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 control_ListRoutes.h
+ * @brief List the icn-light routes
+ *
+ * Implements the "list routes" and "help list routes" nodes of the command tree
+ *
+ */
+#ifndef Control_ListRoutes_h
+#define Control_ListRoutes_h
+
+#include <src/config/controlState.h>
+CommandOps *controlListRoutes_Create(ControlState *state);
+CommandOps *controlListRoutes_HelpCreate(ControlState *state);
+#endif // Control_ListRoutes_h
diff --git a/hicn-light/src/config/controlMapMe.c b/hicn-light/src/config/controlMapMe.c
new file mode 100755
index 000000000..2253f52b6
--- /dev/null
+++ b/hicn-light/src/config/controlMapMe.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+
+#include <src/config/controlMapMe.h>
+#include <src/config/controlMapMeDiscovery.h>
+#include <src/config/controlMapMeEnable.h>
+#include <src/config/controlMapMeRetx.h>
+#include <src/config/controlMapMeTimescale.h>
+
+static void _controlMapMe_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlMapMe_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlMapMe_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandMapMe = "mapme";
+static const char *_commandMapMeHelp = "help mapme";
+
+CommandOps *controlMapMe_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMe, _controlMapMe_Init,
+ _controlMapMe_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMe_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeHelp, NULL,
+ _controlMapMe_HelpExecute, commandOps_Destroy);
+}
+
+// =====================================================
+
+static CommandReturn _controlMapMe_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_mapme_enable = controlMapMeEnable_HelpCreate(NULL);
+ CommandOps *ops_mapme_discovery = controlMapMeDiscovery_HelpCreate(NULL);
+ CommandOps *ops_mapme_timescale = controlMapMeTimescale_HelpCreate(NULL);
+ CommandOps *ops_mapme_retx = controlMapMeRetx_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_mapme_enable->command);
+ printf(" %s\n", ops_mapme_discovery->command);
+ printf(" %s\n", ops_mapme_timescale->command);
+ printf(" %s\n", ops_mapme_retx->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_mapme_enable);
+ commandOps_Destroy(&ops_mapme_discovery);
+ commandOps_Destroy(&ops_mapme_timescale);
+ commandOps_Destroy(&ops_mapme_retx);
+
+ return CommandReturn_Success;
+}
+
+static void _controlMapMe_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlMapMeEnable_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeDiscovery_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeTimescale_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeRetx_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMeEnable_Create(state));
+ controlState_RegisterCommand(state, controlMapMeDiscovery_Create(state));
+ controlState_RegisterCommand(state, controlMapMeTimescale_Create(state));
+ controlState_RegisterCommand(state, controlMapMeRetx_Create(state));
+}
+
+static CommandReturn _controlMapMe_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlMapMe_HelpExecute(parser, ops, args);
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlMapMe.h b/hicn-light/src/config/controlMapMe.h
new file mode 100755
index 000000000..d9cfdb82c
--- /dev/null
+++ b/hicn-light/src/config/controlMapMe.h
@@ -0,0 +1,22 @@
+/*
+ * 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 controlMapMe_h
+#define controlMapMe_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMe_Create(ControlState *state);
+CommandOps *controlMapMe_HelpCreate(ControlState *state);
+#endif // controlMapMe_h
diff --git a/hicn-light/src/config/controlMapMeDiscovery.c b/hicn-light/src/config/controlMapMeDiscovery.c
new file mode 100755
index 000000000..f8f4bf082
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeDiscovery.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeDiscovery.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeDiscovery_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlMapMeDiscovery_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeDiscovery = "mapme discovery";
+static const char *_commandMapMeDiscoveryHelp = "help mapme discovery";
+
+// ====================================================
+
+CommandOps *controlMapMeDiscovery_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeDiscovery, NULL,
+ _controlMapMeDiscovery_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeDiscovery_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeDiscoveryHelp, NULL,
+ _controlMapMeDiscovery_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeDiscovery_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme discovery [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeDiscovery_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeDiscovery_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlMapMeDiscovery_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ mapme_activator_command *mapmeDiscoveryCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_activator_command));
+ if (active) {
+ mapmeDiscoveryCommand->activate = ACTIVATE_ON;
+ } else {
+ mapmeDiscoveryCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, MAPME_DISCOVERY, mapmeDiscoveryCommand,
+ sizeof(mapme_activator_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeDiscovery.h b/hicn-light/src/config/controlMapMeDiscovery.h
new file mode 100755
index 000000000..c492fa0ab
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeDiscovery.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_MapMeDiscovery_h
+#define Control_MapMeDiscovery_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeDiscovery_Create(ControlState *state);
+CommandOps *controlMapMeDiscovery_HelpCreate(ControlState *state);
+#endif // Control_MapMeDiscovery_h
diff --git a/hicn-light/src/config/controlMapMeEnable.c b/hicn-light/src/config/controlMapMeEnable.c
new file mode 100755
index 000000000..db77450e5
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeEnable.c
@@ -0,0 +1,101 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeEnable.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeEnable_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlMapMeEnable_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeEnable = "mapme enable";
+static const char *_commandMapMeEnableHelp = "help mapme enable";
+
+// ====================================================
+
+CommandOps *controlMapMeEnable_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeEnable, NULL,
+ _controlMapMeEnable_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeEnable_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeEnableHelp, NULL,
+ _controlMapMeEnable_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeEnable_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme enable [on|off]\n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeEnable_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeEnable_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlMapMeEnable_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ mapme_activator_command *mapmeEnableCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_activator_command));
+ if (active) {
+ mapmeEnableCommand->activate = ACTIVATE_ON;
+ } else {
+ mapmeEnableCommand->activate = ACTIVATE_OFF;
+ }
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, MAPME_ENABLE, mapmeEnableCommand, sizeof(mapme_activator_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeEnable.h b/hicn-light/src/config/controlMapMeEnable.h
new file mode 100755
index 000000000..f7ca6204d
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeEnable.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_MapMeEnable_h
+#define Control_MapMeEnable_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeEnable_Create(ControlState *state);
+CommandOps *controlMapMeEnable_HelpCreate(ControlState *state);
+#endif // Control_MapMeEnable_h
diff --git a/hicn-light/src/config/controlMapMeRetx.c b/hicn-light/src/config/controlMapMeRetx.c
new file mode 100755
index 000000000..bb16b8833
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeRetx.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeRetx.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeRetx_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlMapMeRetx_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeRetx = "mapme retx";
+static const char *_commandMapMeRetxHelp = "help mapme retx";
+
+// ====================================================
+
+CommandOps *controlMapMeRetx_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeRetx, NULL,
+ _controlMapMeRetx_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeRetx_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeRetxHelp, NULL,
+ _controlMapMeRetx_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeRetx_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme retx <milliseconds>n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeRetx_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeRetx_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *rtx = parcList_GetAtIndex(args, 2);
+ if (!utils_IsNumber(rtx)) {
+ printf(
+ "ERROR: retransmission value (expressed in ms) must be a positive "
+ "integer \n");
+ return CommandReturn_Failure;
+ }
+
+ mapme_timing_command *mapmeRetxCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_timing_command));
+ mapmeRetxCommand->timePeriod = (unsigned)strtold(rtx, NULL);
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, MAPME_RETX, mapmeRetxCommand, sizeof(mapme_timing_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeRetx.h b/hicn-light/src/config/controlMapMeRetx.h
new file mode 100755
index 000000000..611bd3663
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeRetx.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_MapMeRetx_h
+#define Control_MapMeRetx_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeRetx_Create(ControlState *state);
+CommandOps *controlMapMeRetx_HelpCreate(ControlState *state);
+#endif // Control_MapMeRetx_h
diff --git a/hicn-light/src/config/controlMapMeTimescale.c b/hicn-light/src/config/controlMapMeTimescale.c
new file mode 100755
index 000000000..9303b4b0f
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeTimescale.c
@@ -0,0 +1,97 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config/controlMapMeTimescale.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlMapMeTimescale_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlMapMeTimescale_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandMapMeTimescale = "mapme timescale";
+static const char *_commandMapMeTimescaleHelp = "help mapme timescale";
+
+// ====================================================
+
+CommandOps *controlMapMeTimescale_Create(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeTimescale, NULL,
+ _controlMapMeTimescale_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlMapMeTimescale_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandMapMeTimescaleHelp, NULL,
+ _controlMapMeTimescale_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlMapMeTimescale_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("mapme timescale <milliseconds>n");
+ printf("\n");
+
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlMapMeTimescale_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 3) {
+ _controlMapMeTimescale_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *ts = parcList_GetAtIndex(args, 2);
+ if (!utils_IsNumber(ts)) {
+ printf(
+ "ERROR: timescale value (expressed in ms) must be a positive integer "
+ "\n");
+ return CommandReturn_Failure;
+ }
+
+ mapme_timing_command *mapmeTimescaleCommand =
+ parcMemory_AllocateAndClear(sizeof(mapme_timing_command));
+ mapmeTimescaleCommand->timePeriod = (unsigned)strtold(ts, NULL);
+
+ ControlState *state = ops->closure;
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, MAPME_TIMESCALE, mapmeTimescaleCommand,
+ sizeof(mapme_timing_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlMapMeTimescale.h b/hicn-light/src/config/controlMapMeTimescale.h
new file mode 100755
index 000000000..d4b383696
--- /dev/null
+++ b/hicn-light/src/config/controlMapMeTimescale.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_MapMeTimescale_h
+#define Control_MapMeTimescale_h
+
+#include <src/config/controlState.h>
+CommandOps *controlMapMeTimescale_Create(ControlState *state);
+CommandOps *controlMapMeTimescale_HelpCreate(ControlState *state);
+#endif // Control_MapMeTimescale_h
diff --git a/hicn-light/src/config/controlQuit.c b/hicn-light/src/config/controlQuit.c
new file mode 100755
index 000000000..635fe278f
--- /dev/null
+++ b/hicn-light/src/config/controlQuit.c
@@ -0,0 +1,63 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_Security.h>
+
+#include <src/config/controlQuit.h>
+
+static CommandReturn _controlQuit_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlQuit_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandQuit = "quit";
+static const char *_commandQuitHelp = "help quit";
+
+// ====================================================
+
+CommandOps *controlQuit_Create(ControlState *state) {
+ return commandOps_Create(state, _commandQuit, NULL, _controlQuit_Execute,
+ commandOps_Destroy);
+}
+
+CommandOps *controlQuit_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandQuitHelp, NULL,
+ _controlQuit_HelpExecute, commandOps_Destroy);
+}
+
+// ==============================================
+
+static CommandReturn _controlQuit_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ printf("Exits the interactive control program\n\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlQuit_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ printf("exiting interactive shell\n");
+ return CommandReturn_Exit;
+}
diff --git a/hicn-light/src/config/controlQuit.h b/hicn-light/src/config/controlQuit.h
new file mode 100755
index 000000000..e2ba3540e
--- /dev/null
+++ b/hicn-light/src/config/controlQuit.h
@@ -0,0 +1,29 @@
+/*
+ * 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 control_Quit.h
+ * @brief The quit command
+ *
+ * Implements the "quit" and "help quit" nodes of the command tree
+ *
+ */
+#ifndef Control_Quit_h
+#define Control_Quit_h
+
+#include <src/config/controlState.h>
+CommandOps *controlQuit_Create(ControlState *state);
+CommandOps *controlQuit_HelpCreate(ControlState *state);
+#endif // Control_Quit_h
diff --git a/hicn-light/src/config/controlRemove.c b/hicn-light/src/config/controlRemove.c
new file mode 100755
index 000000000..ede075a1b
--- /dev/null
+++ b/hicn-light/src/config/controlRemove.c
@@ -0,0 +1,92 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlRemove.h>
+#include <src/config/controlRemoveConnection.h>
+#include <src/config/controlRemovePunting.h>
+#include <src/config/controlRemoveRoute.h>
+
+static void _controlRemove_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlRemove_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlRemove_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandRemove = "remove";
+static const char *_commandRemoveHelp = "help remove";
+
+// ====================================================
+
+CommandOps *controlRemove_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemove, _controlRemove_Init,
+ _controlRemove_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRemove_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveHelp, NULL,
+ _controlRemove_HelpExecute, commandOps_Destroy);
+}
+
+// ==============================================
+
+static CommandReturn _controlRemove_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_remove_connection = controlRemoveConnection_Create(NULL);
+ CommandOps *ops_remove_route = controlRemoveRoute_Create(NULL);
+ CommandOps *ops_remove_punting = controlRemovePunting_Create(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_remove_connection->command);
+ printf(" %s\n", ops_remove_route->command);
+ printf(" %s\n", ops_remove_punting->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_remove_connection);
+ commandOps_Destroy(&ops_remove_route);
+ commandOps_Destroy(&ops_remove_punting);
+ return CommandReturn_Success;
+}
+
+static void _controlRemove_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state,
+ controlRemoveConnection_HelpCreate(state));
+ controlState_RegisterCommand(state, controlRemoveRoute_HelpCreate(state));
+ controlState_RegisterCommand(state, controlRemoveConnection_Create(state));
+ controlState_RegisterCommand(state, controlRemoveRoute_Create(state));
+ controlState_RegisterCommand(state, controlRemovePunting_Create(state));
+ controlState_RegisterCommand(state, controlRemovePunting_HelpCreate(state));
+}
+
+static CommandReturn _controlRemove_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlRemove_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlRemove.h b/hicn-light/src/config/controlRemove.h
new file mode 100755
index 000000000..d75ecfe70
--- /dev/null
+++ b/hicn-light/src/config/controlRemove.h
@@ -0,0 +1,29 @@
+/*
+ * 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 control_Remove.h
+ * @brief Implements the remove node of the CLI tree
+ *
+ * Implements the "remove" and "help remove" nodes of the command tree
+ *
+ */
+#ifndef controlRemove_h
+#define controlRemove_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemove_Create(ControlState *state);
+CommandOps *controlRemove_HelpCreate(ControlState *state);
+#endif // controlRemove_h
diff --git a/hicn-light/src/config/controlRemoveConnection.c b/hicn-light/src/config/controlRemoveConnection.c
new file mode 100755
index 000000000..93365ad17
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveConnection.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <src/utils/address.h>
+
+#include <src/config/controlRemoveConnection.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlRemoveConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlRemoveConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandRemoveConnection = "remove connection";
+static const char *_commandRemoveConnectionHelp = "help remove connection";
+
+// ====================================================
+
+CommandOps *controlRemoveConnection_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveConnection, NULL,
+ _controlRemoveConnection_Execute,
+ commandOps_Destroy);
+}
+
+CommandOps *controlRemoveConnection_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveConnectionHelp, NULL,
+ _controlRemoveConnection_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlRemoveConnection_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("command:\n");
+ printf(" remove connection <symbolic|id>\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlRemoveConnection_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 3) {
+ _controlRemoveConnection_HelpExecute(parser, ops, args);
+ return false;
+ }
+
+ if ((strcmp(parcList_GetAtIndex(args, 0), "remove") != 0) ||
+ (strcmp(parcList_GetAtIndex(args, 1), "connection") != 0)) {
+ _controlRemoveConnection_HelpExecute(parser, ops, args);
+ return false;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 2);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ remove_connection_command *removeConnectionCommand =
+ parcMemory_AllocateAndClear(sizeof(remove_connection_command));
+ // fill payload
+ strcpy(removeConnectionCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response =
+ utils_SendRequest(state, REMOVE_CONNECTION, removeConnectionCommand,
+ sizeof(remove_connection_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlRemoveConnection.h b/hicn-light/src/config/controlRemoveConnection.h
new file mode 100755
index 000000000..1dd1af23b
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveConnection.h
@@ -0,0 +1,31 @@
+/*
+ * 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 control_RemoveConnection.h
+ * @brief Remove a connection from the connection table
+ *
+ * Implements the "remove connection" and "help remove connection" nodes of the
+ * CLI tree
+ *
+ */
+
+#ifndef Control_RemoveConnection_h
+#define Control_RemoveConnection_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemoveConnection_Create(ControlState *state);
+CommandOps *controlRemoveConnection_HelpCreate(ControlState *state);
+#endif // Control_RemoveConnection_h
diff --git a/hicn-light/src/config/controlRemovePunting.c b/hicn-light/src/config/controlRemovePunting.c
new file mode 100755
index 000000000..cf4c4fbd4
--- /dev/null
+++ b/hicn-light/src/config/controlRemovePunting.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <src/utils/address.h>
+
+#include <src/config/controlRemovePunting.h>
+
+static CommandReturn _controlRemovePunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlRemovePunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandRemovePunting = "remove punting";
+static const char *_commandRemovePuntingHelp = "help punting connection";
+
+// ====================================================
+
+CommandOps *controlRemovePunting_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemovePunting, NULL,
+ _controlRemovePunting_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRemovePunting_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemovePuntingHelp, NULL,
+ _controlRemovePunting_HelpExecute,
+ commandOps_Destroy);
+}
+
+// ====================================================
+
+// ====================================================
+
+static CommandReturn _controlRemovePunting_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("remove punting <symbolic> <prefix>\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlRemovePunting_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("command not implemented\n");
+ return _controlRemovePunting_HelpExecute(parser, ops, args);
+}
+
+// ==================================================
diff --git a/hicn-light/src/config/controlRemovePunting.h b/hicn-light/src/config/controlRemovePunting.h
new file mode 100755
index 000000000..89b1343e7
--- /dev/null
+++ b/hicn-light/src/config/controlRemovePunting.h
@@ -0,0 +1,27 @@
+/*
+ * 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 control_RemovePunting.h
+ *
+ */
+
+#ifndef Control_RemovePunting_h
+#define Control_RemovePunting_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemovePunting_Create(ControlState *state);
+CommandOps *controlRemovePunting_HelpCreate(ControlState *state);
+#endif // Control_RemovePunting_h
diff --git a/hicn-light/src/config/controlRemoveRoute.c b/hicn-light/src/config/controlRemoveRoute.c
new file mode 100755
index 000000000..b9b4ed1e4
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveRoute.c
@@ -0,0 +1,150 @@
+/*
+ * 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 <src/config.h>
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/utils/address.h>
+
+#include <src/config/controlRemoveRoute.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlRemoveRoute_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlRemoveRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+// ===================================================
+
+static const char *_commandRemoveRoute = "remove route";
+static const char *_commandRemoveRouteHelp = "help remove route";
+
+// ====================================================
+
+CommandOps *controlRemoveRoute_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveRoute, NULL,
+ _controlRemoveRoute_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRemoveRoute_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRemoveRouteHelp, NULL,
+ _controlRemoveRoute_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlRemoveRoute_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("commands:\n");
+ printf(" remove route <symbolic | connid> <prefix>\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlRemoveRoute_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlRemoveRoute_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 2);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, 3);
+ char addr[strlen(prefixStr) + 1];
+
+ // separate address and len
+ char *slash;
+ uint32_t len = 0;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ remove_route_command *removeRouteCommand =
+ parcMemory_AllocateAndClear(sizeof(remove_route_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &removeRouteCommand->address.ipv4) == 1) {
+ if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&removeRouteCommand);
+ return CommandReturn_Failure;
+ }
+ removeRouteCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &removeRouteCommand->address.ipv6) ==
+ 1) {
+ if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&removeRouteCommand);
+ return CommandReturn_Failure;
+ }
+ removeRouteCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&removeRouteCommand);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ removeRouteCommand->len = len;
+ strcpy(removeRouteCommand->symbolicOrConnid, symbolicOrConnid);
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, REMOVE_ROUTE, removeRouteCommand, sizeof(remove_route_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlRemoveRoute.h b/hicn-light/src/config/controlRemoveRoute.h
new file mode 100755
index 000000000..a3c0ee46a
--- /dev/null
+++ b/hicn-light/src/config/controlRemoveRoute.h
@@ -0,0 +1,31 @@
+/*
+ * 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 control_RemoveRoute.h
+ * @brief Remove a route from the FIB
+ *
+ * Implements the "remove route" and "help remove route" nodes of the command
+ * tree
+ *
+ */
+
+#ifndef Control_RemoveRoute_h
+#define Control_RemoveRoute_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRemoveRoute_Create(ControlState *state);
+CommandOps *controlRemoveRoute_HelpCreate(ControlState *state);
+#endif // Control_RemoveRoute_h
diff --git a/hicn-light/src/config/controlRoot.c b/hicn-light/src/config/controlRoot.c
new file mode 100755
index 000000000..5d6c5f98e
--- /dev/null
+++ b/hicn-light/src/config/controlRoot.c
@@ -0,0 +1,134 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <src/config/controlAdd.h>
+#include <src/config/controlCache.h>
+#include <src/config/controlList.h>
+#include <src/config/controlMapMe.h>
+#include <src/config/controlQuit.h>
+#include <src/config/controlRemove.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlSet.h>
+#include <src/config/controlUnset.h>
+
+static void _controlRoot_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlRoot_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlRoot_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandRoot = "";
+static const char *_commandRootHelp = "help";
+
+// ====================================================
+
+CommandOps *controlRoot_Create(ControlState *state) {
+ return commandOps_Create(state, _commandRoot, _controlRoot_Init,
+ _controlRoot_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlRoot_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandRootHelp, NULL,
+ _controlRoot_HelpExecute, commandOps_Destroy);
+}
+
+// ===================================================
+
+static CommandReturn _controlRoot_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ printf("Command-line execution:\n");
+ printf(
+ " controller [--keystore <keystorepath>] [--password <password>] "
+ "command\n");
+ printf("\n");
+ printf("Interactive execution:\n");
+ printf(" controller [--keystore <keystorepath>] [--password <password>]\n");
+ printf("\n");
+ printf(
+ "If the keystore is not specified, the default path is used. Keystore "
+ "must exist prior to running program.\n");
+ printf("If the password is not specified, the user will be prompted.\n");
+ printf("\n");
+
+ CommandOps *ops_help_add = controlAdd_CreateHelp(NULL);
+ CommandOps *ops_help_list = controlList_HelpCreate(NULL);
+ CommandOps *ops_help_quit = controlQuit_HelpCreate(NULL);
+ CommandOps *ops_help_remove = controlRemove_HelpCreate(NULL);
+ CommandOps *ops_help_set = controlSet_HelpCreate(NULL);
+ CommandOps *ops_help_unset = controlUnset_HelpCreate(NULL);
+ CommandOps *ops_help_cache = controlCache_HelpCreate(NULL);
+ CommandOps *ops_help_mapme = controlMapMe_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_help_add->command);
+ printf(" %s\n", ops_help_list->command);
+ printf(" %s\n", ops_help_quit->command);
+ printf(" %s\n", ops_help_remove->command);
+ printf(" %s\n", ops_help_set->command);
+ printf(" %s\n", ops_help_unset->command);
+ printf(" %s\n", ops_help_cache->command);
+ printf(" %s\n", ops_help_mapme->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_help_add);
+ commandOps_Destroy(&ops_help_list);
+ commandOps_Destroy(&ops_help_quit);
+ commandOps_Destroy(&ops_help_remove);
+ commandOps_Destroy(&ops_help_set);
+ commandOps_Destroy(&ops_help_unset);
+ commandOps_Destroy(&ops_help_cache);
+ commandOps_Destroy(&ops_help_mapme);
+
+ return CommandReturn_Success;
+}
+
+static void _controlRoot_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+
+ controlState_RegisterCommand(state, controlAdd_CreateHelp(state));
+ controlState_RegisterCommand(state, controlList_HelpCreate(state));
+ controlState_RegisterCommand(state, controlQuit_HelpCreate(state));
+ controlState_RegisterCommand(state, controlRemove_HelpCreate(state));
+ controlState_RegisterCommand(state, controlSet_HelpCreate(state));
+ controlState_RegisterCommand(state, controlUnset_HelpCreate(state));
+ controlState_RegisterCommand(state, controlCache_HelpCreate(state));
+ controlState_RegisterCommand(state, controlMapMe_HelpCreate(state));
+
+ controlState_RegisterCommand(state, webControlAdd_Create(state));
+ controlState_RegisterCommand(state, controlList_Create(state));
+ controlState_RegisterCommand(state, controlQuit_Create(state));
+ controlState_RegisterCommand(state, controlRemove_Create(state));
+ controlState_RegisterCommand(state, controlSet_Create(state));
+ controlState_RegisterCommand(state, controlUnset_Create(state));
+ controlState_RegisterCommand(state, controlCache_Create(state));
+ controlState_RegisterCommand(state, controlMapMe_Create(state));
+}
+
+static CommandReturn _controlRoot_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return CommandReturn_Success;
+}
+
+// ======================================================================
diff --git a/hicn-light/src/config/controlRoot.h b/hicn-light/src/config/controlRoot.h
new file mode 100755
index 000000000..a62126eba
--- /dev/null
+++ b/hicn-light/src/config/controlRoot.h
@@ -0,0 +1,31 @@
+/*
+ * 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 control_Root.h
+ * @brief Root of the command tree
+ *
+ * Implements the root of the command tree. This is the one module that
+ * needs to be seeded to the control state to build the whole tree.
+ *
+ */
+
+#ifndef Control_Root_h
+#define Control_Root_h
+
+#include <src/config/controlState.h>
+CommandOps *controlRoot_Create(ControlState *state);
+CommandOps *controlRoot_HelpCreate(ControlState *state);
+#endif // Control_Root_h
diff --git a/hicn-light/src/config/controlSet.c b/hicn-light/src/config/controlSet.c
new file mode 100755
index 000000000..c6fd9aa3e
--- /dev/null
+++ b/hicn-light/src/config/controlSet.c
@@ -0,0 +1,88 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_Security.h>
+
+#include <src/config/controlSet.h>
+#include <src/config/controlSetDebug.h>
+#include <src/config/controlSetStrategy.h>
+#include <src/config/controlSetWldr.h>
+
+static void _controlSet_Init(CommandParser *parser, CommandOps *ops);
+static CommandReturn _controlSet_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlSet_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandSet = "set";
+static const char *_commandSetHelp = "help set";
+
+// ===========================================================
+
+CommandOps *controlSet_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSet, _controlSet_Init,
+ _controlSet_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSet_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetHelp, NULL,
+ _controlSet_HelpExecute, commandOps_Destroy);
+}
+
+// ===========================================================
+
+static void _controlSet_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlSetDebug_Create(state));
+ controlState_RegisterCommand(state, controlSetDebug_HelpCreate(state));
+ controlState_RegisterCommand(state, controlSetStrategy_Create(state));
+ controlState_RegisterCommand(state, controlSetStrategy_HelpCreate(state));
+ controlState_RegisterCommand(state, controlSetWldr_Create(state));
+ controlState_RegisterCommand(state, controlSetWldr_HelpCreate(state));
+}
+
+static CommandReturn _controlSet_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ CommandOps *ops_help_set_debug = controlSetDebug_HelpCreate(NULL);
+ CommandOps *ops_help_set_strategy = controlSetStrategy_HelpCreate(NULL);
+ CommandOps *ops_help_set_wldr = controlSetWldr_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_help_set_debug->command);
+ printf(" %s\n", ops_help_set_strategy->command);
+ printf(" %s\n", ops_help_set_wldr->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_help_set_debug);
+ commandOps_Destroy(&ops_help_set_strategy);
+ commandOps_Destroy(&ops_help_set_wldr);
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSet_Execute(CommandParser *parser, CommandOps *ops,
+ PARCList *args) {
+ return _controlSet_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlSet.h b/hicn-light/src/config/controlSet.h
new file mode 100755
index 000000000..4289aad8c
--- /dev/null
+++ b/hicn-light/src/config/controlSet.h
@@ -0,0 +1,29 @@
+/*
+ * 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 control_Set.h
+ * @brief Implements the set node of the CLI tree
+ *
+ * Implements the "set" and "help set" nodes of the command tree
+ *
+ */
+#ifndef Control_Set_h
+#define Control_Set_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSet_Create(ControlState *state);
+CommandOps *controlSet_HelpCreate(ControlState *state);
+#endif // Control_Set_h
diff --git a/hicn-light/src/config/controlSetDebug.c b/hicn-light/src/config/controlSetDebug.c
new file mode 100755
index 000000000..ca432420e
--- /dev/null
+++ b/hicn-light/src/config/controlSetDebug.c
@@ -0,0 +1,74 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlSetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+static CommandReturn _controlSetDebug_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlSetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandSetDebug = "set debug";
+static const char *_commandSetDebugHelp = "help set debug";
+
+// ====================================================
+
+CommandOps *controlSetDebug_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSetDebug, NULL,
+ _controlSetDebug_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSetDebug_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetDebugHelp, NULL,
+ _controlSetDebug_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlSetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("set debug: will enable the debug flag for more verbose output\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSetDebug_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlSetDebug_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+ controlState_SetDebug(state, true);
+ printf("Debug flag set\n\n");
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlSetDebug.h b/hicn-light/src/config/controlSetDebug.h
new file mode 100755
index 000000000..5335ebcab
--- /dev/null
+++ b/hicn-light/src/config/controlSetDebug.h
@@ -0,0 +1,30 @@
+/*
+ * 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 control_SetDebug.h
+ * @brief Sets the debug flag for more verbose output
+ *
+ * Implements the "set debug" and "help set debug" nodes of the command tree
+ *
+ */
+
+#ifndef Control_SetDebug_h
+#define Control_SetDebug_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSetDebug_Create(ControlState *state);
+CommandOps *controlSetDebug_HelpCreate(ControlState *state);
+#endif // Control_SetDebug_h
diff --git a/hicn-light/src/config/controlSetStrategy.c b/hicn-light/src/config/controlSetStrategy.c
new file mode 100755
index 000000000..7b7c11762
--- /dev/null
+++ b/hicn-light/src/config/controlSetStrategy.c
@@ -0,0 +1,183 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+
+#include <src/config/controlSetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlSetStrategy_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlSetStrategy_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandSetStrategy = "set strategy";
+static const char *_commandSetStrategyHelp = "help set strategy";
+
+static const char *_commandSetStrategyOptions[LAST_STRATEGY_VALUE] = {
+ "loadbalancer",
+ "random",
+ "random_per_dash_segment",
+ "loadbalancer_with_delay",
+ "loadbalancer_by_rate",
+ "loadbalancer_best_route"};
+
+// ====================================================
+
+CommandOps *controlSetStrategy_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSetStrategy, NULL,
+ _controlSetStrategy_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSetStrategy_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetStrategyHelp, NULL,
+ _controlSetStrategy_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+strategy_type _validStrategy(const char *strategy) {
+ strategy_type validStrategy = LAST_STRATEGY_VALUE;
+
+ for (int i = 0; i < LAST_STRATEGY_VALUE; i++) {
+ if (strcmp(_commandSetStrategyOptions[i], strategy) == 0) {
+ validStrategy = i;
+ break;
+ }
+ }
+ return validStrategy;
+}
+
+static CommandReturn _controlSetStrategy_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("set strategy <prefix> <strategy>\n");
+ printf("prefix: ipv4/ipv6 address (ex: 1234::/64)\n");
+ printf("strategy: strategy identifier\n");
+ printf("available strategies:\n");
+ printf(" random\n");
+ printf(" loadbalancer\n");
+ printf(" random_per_dash_segment\n");
+ printf(" loadbalancer_with_delay\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSetStrategy_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlSetStrategy_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ if (((strcmp(parcList_GetAtIndex(args, 0), "set") != 0) ||
+ (strcmp(parcList_GetAtIndex(args, 1), "strategy") != 0))) {
+ _controlSetStrategy_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ const char *prefixStr = parcList_GetAtIndex(args, 2);
+ char addr[strlen(prefixStr) + 1];
+ // separate address and len
+ char *slash;
+ uint32_t len = UINT32_MAX;
+ strcpy(addr, prefixStr);
+ slash = strrchr(addr, '/');
+ if (slash != NULL) {
+ len = atoi(slash + 1);
+ *slash = '\0';
+ }
+ if (len == 0) {
+ printf("ERROR: a prefix can not be of length 0\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ set_strategy_command *setStrategyCommand =
+ parcMemory_AllocateAndClear(sizeof(set_strategy_command));
+
+ // check and set IP address
+ if (inet_pton(AF_INET, addr, &setStrategyCommand->address.ipv4) == 1) {
+ if (len == UINT32_MAX) {
+ printf("Netmask not specified: set to 32 by default\n");
+ len = 32;
+ } else if (len > 32) {
+ printf("ERROR: exceeded INET mask length, max=32\n");
+ parcMemory_Deallocate(&setStrategyCommand);
+ return CommandReturn_Failure;
+ }
+ setStrategyCommand->addressType = ADDR_INET;
+ } else if (inet_pton(AF_INET6, addr, &setStrategyCommand->address.ipv6) ==
+ 1) {
+ if (len == UINT32_MAX) {
+ printf("Netmask not specified: set to 128 by default\n");
+ len = 128;
+ } else if (len > 128) {
+ printf("ERROR: exceeded INET6 mask length, max=128\n");
+ parcMemory_Deallocate(&setStrategyCommand);
+ return CommandReturn_Failure;
+ }
+ setStrategyCommand->addressType = ADDR_INET6;
+ } else {
+ printf("Error: %s is not a valid network address \n", addr);
+ parcMemory_Deallocate(&setStrategyCommand);
+ return CommandReturn_Failure;
+ }
+
+ const char *strategyStr = parcList_GetAtIndex(args, 3);
+ // check valid strategy
+ strategy_type strategy;
+ if ((strategy = _validStrategy(strategyStr)) == LAST_STRATEGY_VALUE) {
+ printf("Error: invalid strategy \n");
+ parcMemory_Deallocate(&setStrategyCommand);
+ _controlSetStrategy_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ // Fill remaining payload fields
+ setStrategyCommand->len = len;
+ setStrategyCommand->strategyType = strategy;
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(
+ state, SET_STRATEGY, setStrategyCommand, sizeof(set_strategy_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlSetStrategy.h b/hicn-light/src/config/controlSetStrategy.h
new file mode 100755
index 000000000..53ce8912c
--- /dev/null
+++ b/hicn-light/src/config/controlSetStrategy.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_SetStrategy_h
+#define Control_SetStrategy_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSetStrategy_Create(ControlState *state);
+CommandOps *controlSetStrategy_HelpCreate(ControlState *state);
+#endif // Control_SetStrategy_h
diff --git a/hicn-light/src/config/controlSetWldr.c b/hicn-light/src/config/controlSetWldr.c
new file mode 100755
index 000000000..9da404036
--- /dev/null
+++ b/hicn-light/src/config/controlSetWldr.c
@@ -0,0 +1,122 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlSetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+#include <src/utils/commands.h>
+#include <src/utils/utils.h>
+
+static CommandReturn _controlSetWldr_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlSetWldr_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandSetWldr = "set wldr";
+static const char *_commandSetWldrHelp = "help set wldr";
+
+// ====================================================
+
+CommandOps *controlSetWldr_Create(ControlState *state) {
+ return commandOps_Create(state, _commandSetWldr, NULL,
+ _controlSetWldr_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlSetWldr_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandSetWldrHelp, NULL,
+ _controlSetWldr_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlSetWldr_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("set wldr <on|off> <connection_id>\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlSetWldr_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ ControlState *state = ops->closure;
+
+ if (parcList_Size(args) != 4) {
+ _controlSetWldr_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ if (((strcmp(parcList_GetAtIndex(args, 0), "set") != 0) ||
+ (strcmp(parcList_GetAtIndex(args, 1), "wldr") != 0))) {
+ _controlSetWldr_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ bool active;
+ if (strcmp(parcList_GetAtIndex(args, 2), "on") == 0) {
+ active = true;
+ } else if (strcmp(parcList_GetAtIndex(args, 2), "off") == 0) {
+ active = false;
+ } else {
+ _controlSetWldr_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ // check if valid connid
+ const char *symbolicOrConnid = parcList_GetAtIndex(args, 3);
+
+ if (!utils_ValidateSymbolicName(symbolicOrConnid) &&
+ !utils_IsNumber(symbolicOrConnid)) {
+ printf(
+ "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an "
+ "alpha followed by alphanum;\nconnid must be an integer\n");
+ return CommandReturn_Failure;
+ }
+
+ // allocate command payload
+ set_wldr_command *setWldrCommand =
+ parcMemory_AllocateAndClear(sizeof(set_wldr_command));
+ strcpy(setWldrCommand->symbolicOrConnid, symbolicOrConnid);
+ if (active) {
+ setWldrCommand->activate = ACTIVATE_ON;
+ } else {
+ setWldrCommand->activate = ACTIVATE_OFF;
+ }
+
+ // send message and receive response
+ struct iovec *response = utils_SendRequest(state, SET_WLDR, setWldrCommand,
+ sizeof(set_wldr_command));
+
+ if (!response) { // get NULL pointer
+ return CommandReturn_Failure;
+ }
+
+ parcMemory_Deallocate(&response); // free iovec pointer
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlSetWldr.h b/hicn-light/src/config/controlSetWldr.h
new file mode 100755
index 000000000..59c0b0fe6
--- /dev/null
+++ b/hicn-light/src/config/controlSetWldr.h
@@ -0,0 +1,22 @@
+/*
+ * 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 Control_SetWldr_h
+#define Control_SetWldr_h
+
+#include <src/config/controlState.h>
+CommandOps *controlSetWldr_Create(ControlState *state);
+CommandOps *controlSetWldr_HelpCreate(ControlState *state);
+#endif // Control_SetWldr_h
diff --git a/hicn-light/src/config/controlState.c b/hicn-light/src/config/controlState.c
new file mode 100755
index 000000000..d8260e8e8
--- /dev/null
+++ b/hicn-light/src/config/controlState.c
@@ -0,0 +1,237 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+#include <string.h>
+
+#include <parc/security/parc_Security.h>
+
+#include <parc/algol/parc_List.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Network.h>
+#include <parc/algol/parc_Time.h>
+#include <parc/algol/parc_TreeRedBlack.h>
+
+#include <src/config/commandParser.h>
+#include <src/config/controlRoot.h>
+#include <src/config/controlState.h>
+
+#include <src/utils/commands.h>
+
+#define SRV_IP "127.0.0.1"
+#define PORT 9695
+
+struct controller_state {
+ CommandParser *parser;
+ bool debugFlag;
+
+ void *userdata;
+ struct iovec *(*writeRead)(ControlState *state, struct iovec *msg);
+ int sockfd;
+ char **commandOutput;
+ bool isInteractive;
+};
+
+int controlState_connectToFwdDeamon() {
+ int sockfd;
+ struct sockaddr_in servaddr;
+
+ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ printf("\nSocket Creation Failed \n");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+
+ // Filling server information
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(PORT);
+ servaddr.sin_addr.s_addr = INADDR_ANY;
+
+ // Establish connection
+ if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
+ printf("\nConnection Failed: hicn-light Daemon is not running \n");
+ exit(EXIT_FAILURE);
+ }
+
+ return sockfd;
+}
+
+ControlState *controlState_Create(
+ void *userdata,
+ struct iovec *(*writeRead)(ControlState *state, struct iovec *msg),
+ bool openControllerConnetion) {
+ ControlState *state = parcMemory_AllocateAndClear(sizeof(ControlState));
+ parcAssertNotNull(state, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(ControlState));
+ state->parser = commandParser_Create();
+
+ state->userdata = userdata;
+ state->writeRead = writeRead;
+ state->debugFlag = false;
+ state->commandOutput = NULL;
+ state->isInteractive = true;
+
+ if (openControllerConnetion) {
+ state->sockfd = controlState_connectToFwdDeamon();
+ } else {
+ state->sockfd = 2; // stderr
+ }
+
+ return state;
+}
+
+void controlState_Destroy(ControlState **statePtr) {
+ parcAssertNotNull(statePtr, "Parameter statePtr must be non-null");
+ parcAssertNotNull(*statePtr,
+ "Parameter statePtr must dereference t non-null");
+ ControlState *state = *statePtr;
+ // printf("sockid destroyed: %d\n", state->sockfd);
+ // close the connection with the fwd deamon
+ shutdown(state->sockfd, 2);
+
+ commandParser_Destroy(&state->parser);
+ parcMemory_Deallocate((void **)&state);
+ *statePtr = NULL;
+}
+
+void controlState_SetDebug(ControlState *state, bool debugFlag) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ state->debugFlag = debugFlag;
+ commandParser_SetDebug(state->parser, debugFlag);
+}
+
+bool controlState_GetDebug(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return state->debugFlag;
+}
+
+void controlState_RegisterCommand(ControlState *state, CommandOps *ops) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ commandParser_RegisterCommand(state->parser, ops);
+}
+
+struct iovec *controlState_WriteRead(ControlState *state, struct iovec *msg) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ parcAssertNotNull(msg, "Parameter msg must be non-null");
+
+ return state->writeRead(state, msg);
+}
+
+static PARCList *_controlState_ParseStringIntoTokens(
+ const char *originalString) {
+ PARCList *list =
+ parcList(parcArrayList_Create(parcArrayList_StdlibFreeFunction),
+ PARCArrayListAsPARCList);
+
+ char *token;
+
+ char *tofree =
+ parcMemory_StringDuplicate(originalString, strlen(originalString) + 1);
+ char *string = tofree;
+
+ while ((token = strsep(&string, " \t\n")) != NULL) {
+ if (strlen(token) > 0) {
+ parcList_Add(list, strdup(token));
+ }
+ }
+
+ parcMemory_Deallocate((void **)&tofree);
+
+ return list;
+}
+
+CommandReturn controlState_DispatchCommand(ControlState *state,
+ PARCList *args) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return commandParser_DispatchCommand(state->parser, args);
+}
+
+int controlState_Interactive(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ char *line = NULL;
+ size_t linecap = 0;
+ CommandReturn controlReturn = CommandReturn_Success;
+
+ while (controlReturn != CommandReturn_Exit && !feof(stdin)) {
+ fputs("> ", stdout);
+ fflush(stdout);
+ ssize_t failure = getline(&line, &linecap, stdin);
+ parcAssertTrue(failure > -1, "Error getline");
+
+ PARCList *args = _controlState_ParseStringIntoTokens(line);
+ controlReturn = controlState_DispatchCommand(state, args);
+ // release and get command
+ parcList_Release(&args);
+ }
+ return 0;
+}
+
+void controlState_SetCommandOutput(ControlState *state, char **commandData) {
+ state->commandOutput = commandData;
+}
+
+void controlState_ReleaseCommandOutput(ControlState *state, char **commandData,
+ size_t commandLenght) {
+ for (size_t i = 0; i < commandLenght; i++) {
+ parcMemory_Deallocate(&commandData[i]);
+ }
+ parcMemory_Deallocate(&commandData);
+ state->commandOutput = NULL;
+}
+
+char **controlState_GetCommandOutput(ControlState *state) {
+ return state->commandOutput;
+}
+
+// size_t
+// controlState_GetCommandLen(ControlState *state){
+
+// }
+
+void controlState_SetInteractiveFlag(ControlState *state, bool interactive) {
+ state->isInteractive = interactive;
+}
+
+bool controlState_IsInteractive(ControlState *state) {
+ return state->isInteractive;
+}
+
+int controlState_GetSockfd(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return state->sockfd;
+}
+
+void *controlState_GetUserdata(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ return state->userdata;
+}
+
+bool controlState_isConfigFile(ControlState *state) {
+ parcAssertNotNull(state, "Parameter state must be non-null");
+ if (state->sockfd != 2) {
+ return false;
+ } else {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/hicn-light/src/config/controlState.h b/hicn-light/src/config/controlState.h
new file mode 100755
index 000000000..905c56c30
--- /dev/null
+++ b/hicn-light/src/config/controlState.h
@@ -0,0 +1,233 @@
+/*
+ * 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 controlState.h
+ * @brief A control program for hicn-light using CLI commands
+ *
+ * Implements the state machine for the control program. It takes a "writeRead"
+ * function as part of the constructor. This abstracts out the backend. It
+ * could be a Portal from hicnLightControl program down to the forwarder or it
+ * could be an internal function within hicn-light.
+ *
+ */
+
+#ifndef control_h
+#define control_h
+
+#include <parc/algol/parc_List.h>
+#include <src/config/commandParser.h>
+
+#include <src/utils/commands.h>
+
+struct controller_state;
+typedef struct controller_state ControlState;
+
+/**
+ * controlState_Create
+ *
+ * Creates the global state for the Control program. The user provides the
+ * writeRead function for sending and receiving the message wrapping command
+ * arguments. For configuration file inside hicn-light, it would make direct
+ * calls to Configuration -> Dispatcher.
+ *
+ * @param [in] userdata A closure passed back to the user when calling
+ * writeRead.
+ * @param [in] writeRead The function to write then read configuration messages
+ * to hicn-light
+ *
+ * @return non-null The control state
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+
+ControlState *controlState_Create(
+ void *userdata,
+ struct iovec *(*writeRead)(ControlState *state, struct iovec *msg),
+ bool openControllerConnetion);
+
+/**
+ * Destroys the control state, closing all network connections
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void controlState_Destroy(ControlState **statePtr);
+
+/**
+ * Registers a CommandOps with the system.
+ *
+ * Each command has its complete command prefix in the "command" field.
+ * RegisterCommand will put these command prefixes in to a tree and then match
+ * what a user types against the longest-matching prefix in the tree. If
+ * there's a match, it will call the "execute" function.
+ *
+ * @param [in] state An allocated ControlState
+ * @param [in] command The command to register with the system
+ *
+ * Example:
+ * @code
+ * static CommandReturn
+ * control_Root_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Root Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * static CommandReturn
+ * control_FooBar_Execute(CommandParser *parser, CommandOps *ops, PARCList
+ * *args)
+ * {
+ * printf("Foo Bar Command\n");
+ * return CommandReturn_Success;
+ * }
+ *
+ * const CommandOps control_Root = {
+ * .command = "", // empty string for root
+ * .init = NULL,
+ * .execute = control_Root_Execute
+ * };
+ *
+ * const CommandOps control_FooBar = {
+ * .command = "foo bar", // empty string for root
+ * .init = NULL,
+ * .execute = control_FooBar_Execute
+ * };
+ *
+ * void startup(void)
+ * {
+ * ControlState *state = controlState_Create("happy", "day");
+ * controlState_RegisterCommand(state, control_FooBar);
+ * controlState_RegisterCommand(state, control_Root);
+ *
+ * // this executes "root"
+ * controlState_DispatchCommand(state, "foo");
+ * controlState_Destroy(&state);
+ * }
+ * @endcode
+ */
+void controlState_RegisterCommand(ControlState *state, CommandOps *command);
+
+/**
+ * Performs a longest-matching prefix of the args to the command tree
+ *
+ * The command tree is created with controlState_RegisterCommand.
+ *
+ * @param [in] state The allocated ControlState
+ * @param [in] args Each command_line word parsed to the ordered list
+ *
+ * @return CommandReturn_Success the command was successful
+ * @return CommandReturn_Failure the command failed or was not found
+ * @return CommandReturn_Exit the command indicates that the interactive mode
+ * should exit
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CommandReturn controlState_DispatchCommand(ControlState *state, PARCList *args);
+
+/**
+ * Begin an interactive shell
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+int controlState_Interactive(ControlState *state);
+
+/**
+ * Write then Read a command
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+struct iovec *controlState_WriteRead(ControlState *state, struct iovec *msg);
+
+/**
+ * Sets the Debug mode, which will print out much more information.
+ *
+ * Prints out much more diagnostic information about what hicn-light controller
+ * is doing. yes, you would make a CommandOps to set and unset this :)
+ *
+ * @param [in] debugFlag true means to print debug info, false means to turn it
+ * off
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void controlState_SetDebug(ControlState *state, bool debugFlag);
+
+/**
+ * Returns the debug state of ControlState
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool controlState_GetDebug(ControlState *state);
+#endif // control_h
+
+void controlState_SetCommandOutput(ControlState *state, char **commandData);
+
+void controlState_ReleaseCommandOutput(ControlState *state, char **commandData,
+ size_t commandLenght);
+
+char **controlState_GetCommandOutput(ControlState *state);
+
+void controlState_SetInteractiveFlag(ControlState *state, bool interactive);
+
+bool controlState_IsInteractive(ControlState *state);
+
+void *controlState_GetUserdata(ControlState *state);
+
+bool controlState_isConfigFile(ControlState *state);
+
+int controlState_GetSockfd(ControlState *state);
diff --git a/hicn-light/src/config/controlUnset.c b/hicn-light/src/config/controlUnset.c
new file mode 100755
index 000000000..2da6a6518
--- /dev/null
+++ b/hicn-light/src/config/controlUnset.c
@@ -0,0 +1,78 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/security/parc_Security.h>
+
+#include <src/config/controlUnset.h>
+#include <src/config/controlUnsetDebug.h>
+
+static void _controlUnset_Init(CommandParser *parser, CommandOps *ops);
+
+static CommandReturn _controlUnset_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+static CommandReturn _controlUnset_HelpExecute(CommandParser *parser,
+ CommandOps *ops, PARCList *args);
+
+static const char *_commandUnset = "unset";
+static const char *_commandUnsetHelp = "help unset";
+
+// ===========================================================
+
+CommandOps *controlUnset_Create(ControlState *state) {
+ return commandOps_Create(state, _commandUnset, _controlUnset_Init,
+ _controlUnset_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlUnset_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandUnsetHelp, NULL,
+ _controlUnset_HelpExecute, commandOps_Destroy);
+}
+
+// ===========================================================
+
+static void _controlUnset_Init(CommandParser *parser, CommandOps *ops) {
+ ControlState *state = ops->closure;
+ controlState_RegisterCommand(state, controlUnsetDebug_Create(state));
+ controlState_RegisterCommand(state, controlUnsetDebug_HelpCreate(state));
+}
+
+static CommandReturn _controlUnset_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ CommandOps *ops_help_unset_debug = controlUnsetDebug_HelpCreate(NULL);
+
+ printf("Available commands:\n");
+ printf(" %s\n", ops_help_unset_debug->command);
+ printf("\n");
+
+ commandOps_Destroy(&ops_help_unset_debug);
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlUnset_Execute(CommandParser *parser,
+ CommandOps *ops, PARCList *args) {
+ return _controlUnset_HelpExecute(parser, ops, args);
+}
diff --git a/hicn-light/src/config/controlUnset.h b/hicn-light/src/config/controlUnset.h
new file mode 100755
index 000000000..6eeb983f7
--- /dev/null
+++ b/hicn-light/src/config/controlUnset.h
@@ -0,0 +1,29 @@
+/*
+ * 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 control_Unset.h
+ * @brief Implements the unset node of the CLI tree
+ *
+ * Implements the "unset" and "help unset" nodes of the command tree
+ *
+ */
+#ifndef Control_Unset_h
+#define Control_Unset_h
+
+#include <src/config/controlState.h>
+CommandOps *controlUnset_Create(ControlState *state);
+CommandOps *controlUnset_HelpCreate(ControlState *state);
+#endif // Control_Unset_h
diff --git a/hicn-light/src/config/controlUnsetDebug.c b/hicn-light/src/config/controlUnsetDebug.c
new file mode 100755
index 000000000..4892bd513
--- /dev/null
+++ b/hicn-light/src/config/controlUnsetDebug.c
@@ -0,0 +1,77 @@
+/*
+ * 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 <src/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <parc/assert/parc_Assert.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include <src/config/controlUnsetDebug.h>
+#include <src/core/dispatcher.h>
+#include <src/core/forwarder.h>
+
+static CommandReturn _controlUnsetDebug_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+static CommandReturn _controlUnsetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args);
+
+static const char *_commandUnsetDebug = "unset debug";
+static const char *_commandUnsetDebugHelp = "help unset debug";
+
+// ====================================================
+
+CommandOps *controlUnsetDebug_Create(ControlState *state) {
+ return commandOps_Create(state, _commandUnsetDebug, NULL,
+ _controlUnsetDebug_Execute, commandOps_Destroy);
+}
+
+CommandOps *controlUnsetDebug_HelpCreate(ControlState *state) {
+ return commandOps_Create(state, _commandUnsetDebugHelp, NULL,
+ _controlUnsetDebug_HelpExecute, commandOps_Destroy);
+}
+
+// ====================================================
+
+static CommandReturn _controlUnsetDebug_HelpExecute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ printf("unset debug: will disable the debug flag\n");
+ printf("\n");
+ return CommandReturn_Success;
+}
+
+static CommandReturn _controlUnsetDebug_Execute(CommandParser *parser,
+ CommandOps *ops,
+ PARCList *args) {
+ if (parcList_Size(args) != 2) {
+ _controlUnsetDebug_HelpExecute(parser, ops, args);
+ return CommandReturn_Failure;
+ }
+
+ ControlState *state = ops->closure;
+ controlState_SetDebug(state, false);
+ printf("Debug flag cleared\n\n");
+
+ return CommandReturn_Success;
+}
diff --git a/hicn-light/src/config/controlUnsetDebug.h b/hicn-light/src/config/controlUnsetDebug.h
new file mode 100755
index 000000000..e34f8aa5f
--- /dev/null
+++ b/hicn-light/src/config/controlUnsetDebug.h
@@ -0,0 +1,30 @@
+/*
+ * 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 control_UnsetDebug.h
+ * @brief Unsets the debug flag for more verbose output
+ *
+ * Implements the "unset debug" and "help unset debug" nodes of the CLI tree
+ *
+ */
+
+#ifndef Control_UnsetDebug_h
+#define Control_UnsetDebug_h
+
+#include <src/config/controlState.h>
+CommandOps *controlUnsetDebug_Create(ControlState *state);
+CommandOps *controlUnsetDebug_HelpCreate(ControlState *state);
+#endif // Control_UnsetDebug_h
diff --git a/hicn-light/src/config/symbolicNameTable.c b/hicn-light/src/config/symbolicNameTable.c
new file mode 100755
index 000000000..ccf416d67
--- /dev/null
+++ b/hicn-light/src/config/symbolicNameTable.c
@@ -0,0 +1,175 @@
+/*
+ * 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 <ctype.h>
+#include <parc/algol/parc_Hash.h>
+#include <parc/algol/parc_HashCodeTable.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/assert/parc_Assert.h>
+#include <src/config.h>
+#include <stdio.h>
+
+#include <src/config/symbolicNameTable.h>
+
+struct symblic_name_table {
+ PARCHashCodeTable *symbolicNameTable;
+ PARCHashCodeTable *indexToNameTable;
+};
+
+// ========================================================================================
+// symbolic name table functions
+
+static bool _symbolicNameEquals(const void *keyA, const void *keyB) {
+ return (strcasecmp((const char *)keyA, (const char *)keyB) == 0);
+}
+
+static HashCodeType _symbolicNameHash(const void *keyA) {
+ const char *str = (const char *)keyA;
+ size_t length = strlen(str);
+ return parcHash32_Data(str, length);
+}
+
+static bool _connectionIdEquals(const void *keyA, const void *keyB) {
+ unsigned idA = *((unsigned *)keyA);
+ unsigned idB = *((unsigned *)keyB);
+ return (idA == idB);
+}
+
+static HashCodeType _connectionIdHash(const void *keyA) {
+ unsigned idA = *((unsigned *)keyA);
+ return parcHash32_Int32(idA);
+}
+
+// ========================================================================================
+
+SymbolicNameTable *symbolicNameTable_Create(void) {
+ SymbolicNameTable *table = parcMemory_Allocate(sizeof(SymbolicNameTable));
+
+ if (table) {
+ // key = char *
+ // value = uint32_t *
+ table->symbolicNameTable = parcHashCodeTable_Create(
+ _symbolicNameEquals, _symbolicNameHash, parcMemory_DeallocateImpl,
+ parcMemory_DeallocateImpl);
+ table->indexToNameTable = parcHashCodeTable_Create(
+ _connectionIdEquals, _connectionIdHash, parcMemory_DeallocateImpl,
+ parcMemory_DeallocateImpl);
+ }
+
+ return table;
+}
+
+void symbolicNameTable_Destroy(SymbolicNameTable **tablePtr) {
+ SymbolicNameTable *table = *tablePtr;
+ parcHashCodeTable_Destroy(&table->symbolicNameTable);
+ // parcHashCodeTable_Destroy(&table->indexToNameTable);
+ parcMemory_Deallocate((void **)&table);
+ *tablePtr = NULL;
+}
+
+static char *_createKey(const char *symbolicName) {
+ char *key = parcMemory_StringDuplicate(symbolicName, strlen(symbolicName));
+
+ // convert key to upper case
+ char *p = key;
+
+ // keeps looping until the first null
+ while ((*p = toupper(*p))) {
+ p++;
+ }
+ return key;
+}
+
+bool symbolicNameTable_Exists(SymbolicNameTable *table,
+ const char *symbolicName) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+
+ char *key = _createKey(symbolicName);
+ bool found = (parcHashCodeTable_Get(table->symbolicNameTable, key) != NULL);
+ parcMemory_Deallocate((void **)&key);
+ return found;
+}
+
+void symbolicNameTable_Remove(SymbolicNameTable *table,
+ const char *symbolicName) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+
+ char *key = _createKey(symbolicName);
+
+ unsigned id = symbolicNameTable_Get(table, symbolicName);
+ uint32_t *value = parcMemory_Allocate(sizeof(uint32_t));
+ *value = id;
+
+ parcHashCodeTable_Del(table->symbolicNameTable, key);
+ parcHashCodeTable_Del(table->indexToNameTable, value);
+ parcMemory_Deallocate((void **)&key);
+ parcMemory_Deallocate((void **)&value);
+}
+
+bool symbolicNameTable_Add(SymbolicNameTable *table, const char *symbolicName,
+ unsigned connid) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+ parcAssertTrue(connid < UINT32_MAX, "Parameter connid must be less than %u",
+ UINT32_MAX);
+
+ char *key = _createKey(symbolicName);
+
+ uint32_t *value = parcMemory_Allocate(sizeof(uint32_t));
+ *value = connid;
+
+ bool success = parcHashCodeTable_Add(table->symbolicNameTable, key, value);
+ success = parcHashCodeTable_Add(table->indexToNameTable, value, key);
+ if (!success) {
+ parcMemory_Deallocate((void **)&key);
+ parcMemory_Deallocate((void **)&value);
+ }
+
+ return success;
+}
+
+unsigned symbolicNameTable_Get(SymbolicNameTable *table,
+ const char *symbolicName) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+ parcAssertNotNull(symbolicName, "Parameter symbolicName must be non-null");
+
+ unsigned connid = UINT32_MAX;
+
+ char *key = _createKey(symbolicName);
+
+ uint32_t *value = parcHashCodeTable_Get(table->symbolicNameTable, key);
+ if (value) {
+ connid = *value;
+ }
+
+ parcMemory_Deallocate((void **)&key);
+ return connid;
+}
+
+const char *symbolicNameTable_GetNameByIndex(SymbolicNameTable *table,
+ unsigned id) {
+ parcAssertNotNull(table, "Parameter table must be non-null");
+
+ uint32_t *value = parcMemory_Allocate(sizeof(uint32_t));
+ *value = id;
+
+ const char *name = parcHashCodeTable_Get(table->indexToNameTable, value);
+ if (name == NULL) name = "";
+
+ parcMemory_Deallocate((void **)&value);
+ return name;
+}
diff --git a/hicn-light/src/config/symbolicNameTable.h b/hicn-light/src/config/symbolicNameTable.h
new file mode 100755
index 000000000..69919cf00
--- /dev/null
+++ b/hicn-light/src/config/symbolicNameTable.h
@@ -0,0 +1,131 @@
+/*
+ * 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 symbolicNameTable.h
+ * @brief The symbolic name table maps a string name to a connection id
+ *
+ * When configuring tunnels/connections, the user provides a string name
+ * (symbolic name) that they will use to refer to that connection. The symblic
+ * name table translates that symbolic name to a connection id.
+ *
+ */
+
+#ifndef symbolicNameTable_h
+#define symbolicNameTable_h
+
+struct symblic_name_table;
+typedef struct symblic_name_table SymbolicNameTable;
+
+#include <stdbool.h>
+
+/**
+ * Creates a symbolic name table
+ *
+ * Allocates a SymbolicNameTable, which will store the symbolic names
+ * in a hash table.
+ *
+ * @retval non-null An allocated SymbolicNameTable
+ * @retval null An error
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+SymbolicNameTable *symbolicNameTable_Create(void);
+
+/**
+ * Destroys a name table
+ *
+ * All keys and data are released.
+ *
+ * @param [in,out] tablePtr A pointer to a SymbolicNameTable, which will be
+ * NULL'd
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+void symbolicNameTable_Destroy(SymbolicNameTable **tablePtr);
+
+/**
+ * Checks if the name (case insensitive) is in the table
+ *
+ * Does a case-insensitive match to see if the name is in the table
+ *
+ * @param [in] table An allocated SymbolicNameTable
+ * @param [in] symbolicName The name to check for
+ *
+ * @retval true The name is in the table
+ * @retval false The name is not in the talbe
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool symbolicNameTable_Exists(SymbolicNameTable *table,
+ const char *symbolicName);
+
+/**
+ * Adds a (name, connid) pair to the table.
+ *
+ * The name is stored case insensitive. The value UINT_MAX is used to indicate
+ * a non-existent key, so it should not be stored as a value in the table.
+ *
+ * @param [in] table An allocated SymbolicNameTable
+ * @param [in] symbolicName The name to save (will make a copy)
+ * @param [in] connid The connection id to associate with the name
+ *
+ * @retval true The pair was added
+ * @retval false The pair was not added (likely duplicate key)
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+bool symbolicNameTable_Add(SymbolicNameTable *table, const char *symbolicName,
+ unsigned connid);
+
+/**
+ * Returns the connection id associated with the symbolic name
+ *
+ * This function will look for the given name (case insensitive) and return the
+ * corresponding connid. If the name is not in the table, the function will
+ * return UINT_MAX.
+ *
+ * @param [in] table An allocated SymbolicNameTable
+ * @param [in] symbolicName The name to retrieve
+ *
+ * @retval UINT_MAX symbolicName not found
+ * @retval number the corresponding connid.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+unsigned symbolicNameTable_Get(SymbolicNameTable *table,
+ const char *symbolicName);
+
+void symbolicNameTable_Remove(SymbolicNameTable *table,
+ const char *symbolicName);
+const char *symbolicNameTable_GetNameByIndex(SymbolicNameTable *table,
+ unsigned id);
+
+#endif /* defined(symbolicNameTable_h) */