diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2019-01-17 13:47:57 +0100 |
---|---|---|
committer | Luca Muscariello <lumuscar+fdio@cisco.com> | 2019-01-17 16:32:51 +0100 |
commit | bac3da61644515f05663789b122554dc77549286 (patch) | |
tree | 898210bc8e70371d77de7d446a26c5dd4fd1165a /hicn-light/src/config | |
parent | d5165246787301d0f13b646fda5e8a8567aef5ac (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')
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 **)©); + } + } + } + + 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) */ |