From 21b304b46a347772c1338b22fba6a15291bb2945 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Sun, 17 Apr 2016 12:08:49 +0200 Subject: ipcpd: initial IPC processes Basic functions for implementation of IPC processes, and implementation of core functions of the shim IPCP over UDP. Updates to the build system to compile these IPC processes, as well as some fixes in the irmd (rudimentary capturing exit signals) and some fixes in the library, mainly relating to the messaging. Basic implementation of creation / bootstrapping / deletion of the shim UDP. Placeholders for other functions. --- CMakeLists.txt | 2 +- include/ouroboros/config.h.in | 12 +- include/ouroboros/dif_config.h | 4 +- include/ouroboros/flow.h | 14 +- src/ipcpd/CMakeLists.txt | 28 +- src/ipcpd/dt_const.h | 44 --- src/ipcpd/ipcp-data.c | 477 +++++++++++++++++++++++++++++++ src/ipcpd/ipcp-data.h | 91 ++++++ src/ipcpd/ipcp-ops.h | 59 ++++ src/ipcpd/ipcp.c | 195 +++++++++++++ src/ipcpd/ipcp.h | 48 ++++ src/ipcpd/main.c | 15 - src/ipcpd/normal/CMakeLists.txt | 32 +++ src/ipcpd/normal/dt_const.h | 44 +++ src/ipcpd/normal/main.c | 15 + src/ipcpd/normal/pci.c | 146 ++++++++++ src/ipcpd/normal/pci.h | 42 +++ src/ipcpd/normal/shm_pci.c | 146 ++++++++++ src/ipcpd/normal/shm_pci.h | 43 +++ src/ipcpd/pci.c | 146 ---------- src/ipcpd/pci.h | 42 --- src/ipcpd/shim-udp/CMakeLists.txt | 31 ++ src/ipcpd/shim-udp/main.c | 323 +++++++++++++++++++++ src/ipcpd/shim-udp/tests/CMakeLists.txt | 33 +++ src/ipcpd/shim-udp/tests/shim_udp_test.c | 103 +++++++ src/ipcpd/shm_pci.c | 146 ---------- src/ipcpd/shm_pci.h | 43 --- src/irmd/main.c | 49 +++- src/lib/dif_config.proto | 25 +- src/lib/flow.c | 6 +- src/lib/ipcp.c | 142 +++++---- src/lib/ipcpd_messages.proto | 20 +- src/lib/irm.c | 10 +- src/lib/irmd_messages.proto | 27 +- src/lib/sockets.c | 7 +- src/lib/utils.c | 2 +- src/tools/irm/irm_bootstrap_ipcp.c | 14 +- 37 files changed, 2043 insertions(+), 583 deletions(-) delete mode 100644 src/ipcpd/dt_const.h create mode 100644 src/ipcpd/ipcp-data.c create mode 100644 src/ipcpd/ipcp-data.h create mode 100644 src/ipcpd/ipcp-ops.h create mode 100644 src/ipcpd/ipcp.c create mode 100644 src/ipcpd/ipcp.h delete mode 100644 src/ipcpd/main.c create mode 100644 src/ipcpd/normal/CMakeLists.txt create mode 100644 src/ipcpd/normal/dt_const.h create mode 100644 src/ipcpd/normal/main.c create mode 100644 src/ipcpd/normal/pci.c create mode 100644 src/ipcpd/normal/pci.h create mode 100644 src/ipcpd/normal/shm_pci.c create mode 100644 src/ipcpd/normal/shm_pci.h delete mode 100644 src/ipcpd/pci.c delete mode 100644 src/ipcpd/pci.h create mode 100644 src/ipcpd/shim-udp/CMakeLists.txt create mode 100644 src/ipcpd/shim-udp/main.c create mode 100644 src/ipcpd/shim-udp/tests/CMakeLists.txt create mode 100644 src/ipcpd/shim-udp/tests/shim_udp_test.c delete mode 100644 src/ipcpd/shm_pci.c delete mode 100644 src/ipcpd/shm_pci.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 243e5d6f..1d31262d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,8 +54,8 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ouroboros.pc" enable_testing() add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) -add_subdirectory(include) add_subdirectory(src) +add_subdirectory(include) # Uninstall target configure_file( diff --git a/include/ouroboros/config.h.in b/include/ouroboros/config.h.in index 01d7888e..6abce97a 100644 --- a/include/ouroboros/config.h.in +++ b/include/ouroboros/config.h.in @@ -23,10 +23,12 @@ #ifndef OUROBOROS_CONFIG #define OUROBOROS_CONFIG -#define PROJECT_NAME "@CMAKE_PROJECT_NAME@" -#define PROJECT_VERSION "@PACKAGE_VERSION@" -#define INSTALL_DIR "@CMAKE_INSTALL_PREFIX@" -#define BUILD_TYPE "@CMAKE_BUILD_TYPE@" -#define _POSIX_C_SOURCE 199506L +#define PROJECT_NAME "@CMAKE_PROJECT_NAME@" +#define PROJECT_VERSION "@PACKAGE_VERSION@" +#define INSTALL_DIR "@CMAKE_INSTALL_PREFIX@" +#define BUILD_TYPE "@CMAKE_BUILD_TYPE@" +#define _POSIX_C_SOURCE 199506L +#define IPCP_SHIM_UDP_EXEC "@IPCP_SHIM_UDP_TARGET@" +#define IPCP_NORMAL_EXEC "@IPCP_NORMAL_TARGET@" #endif diff --git a/include/ouroboros/dif_config.h b/include/ouroboros/dif_config.h index 91b44cb1..5d489b0c 100644 --- a/include/ouroboros/dif_config.h +++ b/include/ouroboros/dif_config.h @@ -21,12 +21,13 @@ */ #include +#include #ifndef OUROBOROS_DIF_CONFIG_H #define OUROBOROS_DIF_CONFIG_H enum ipcp_type { - IPCP_NORMAL = 1, + IPCP_NORMAL = 0, IPCP_SHIM_UDP }; @@ -53,6 +54,7 @@ struct dif_config { /* Shim UDP */ struct { uint32_t ip_addr; + uint32_t dns_addr; }; }; }; diff --git a/include/ouroboros/flow.h b/include/ouroboros/flow.h index 7d8c311e..000de5ad 100644 --- a/include/ouroboros/flow.h +++ b/include/ouroboros/flow.h @@ -24,7 +24,7 @@ #define OUROBOROS_FLOW_H #include - +#include #include /* same values as fcntl.h */ @@ -39,17 +39,19 @@ #define FLOW_O_INVALID (FLOW_O_WRONLY | FLOW_O_RDWR) enum flow_state { - FLOW_INIT = 0, + FLOW_NULL = 0, FLOW_ALLOCATED, FLOW_PENDING }; typedef struct flow { - int32_t port_id; - uint16_t oflags; - enum flow_state state; + struct list_head list; + + int32_t port_id; + uint16_t oflags; + enum flow_state state; - pthread_mutex_t lock; + pthread_mutex_t lock; } flow_t; flow_t * flow_create(int32_t port_id); diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index bcb5b986..6311e3dc 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -1,26 +1,8 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -set(SOURCE_FILES +set(IPCP_SOURCES # Add source files here - main.c - pci.c - shm_pci.c + ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c + ${CMAKE_CURRENT_SOURCE_DIR}/ipcp-data.c ) -add_executable (ipcpd ${SOURCE_FILES}) - -target_link_libraries (ipcpd LINK_PUBLIC ouroboros) - -include(MacroAddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd -DCONFIG_OUROBOROS_DEBUG) -endif (CMAKE_BUILD_TYPE MATCHES Debug) - -install(TARGETS ipcpd RUNTIME DESTINATION bin) - -# Enable once ipcpd has tests -# add_subdirectory(tests) +add_subdirectory(normal) +add_subdirectory(shim-udp) diff --git a/src/ipcpd/dt_const.h b/src/ipcpd/dt_const.h deleted file mode 100644 index bc0c1466..00000000 --- a/src/ipcpd/dt_const.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Data Transfer Constants for the IPCP - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef IPCP_DT_CONST_H -#define IPCP_DT_CONST_H - -#include "ouroboros/common.h" - -struct ipcp_dtp_const { - /* sizes in octets */ - uint8_t addr_size; - uint8_t cep_id_size; - uint8_t pdu_length_size; - uint8_t seqno_size; - uint8_t qos_id_size; - /* uint8_t ctrl_sqnum_sz; is this in the spec?? */ -}; - -struct ipcp_dup_const { - uint8_t ttl_size; - uint8_t chk_size; -}; - -#endif /* IPCP_DT_CONST_H */ diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c new file mode 100644 index 00000000..17649b42 --- /dev/null +++ b/src/ipcpd/ipcp-data.c @@ -0,0 +1,477 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process utilities + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "ipcp-data.h" +#include +#include +#include +#include + +#define OUROBOROS_PREFIX "ipcp-utils" + +#include + +#include +#include + +struct reg_entry { + struct list_head list; + char * ap_name; + uint32_t reg_ap_id; +}; + +struct dir_entry { + struct list_head list; + char * ap_name; + uint64_t addr; +}; + +static struct reg_entry * reg_entry_create(const char * ap_name, + uint32_t reg_ap_id) +{ + struct reg_entry * entry = malloc(sizeof *entry); + if (entry == NULL) + return NULL; + + entry->reg_ap_id = reg_ap_id; + entry->ap_name = strdup(ap_name); + if (entry->ap_name == NULL) + return NULL; + + return entry; +} + +static void reg_entry_destroy(struct reg_entry * entry) +{ + if (entry == NULL) + return; + + free(entry->ap_name); + free(entry); +} + +static struct dir_entry * dir_entry_create(const char * ap_name, + uint64_t addr) +{ + struct dir_entry * entry = malloc(sizeof *entry); + if (entry == NULL) + return NULL; + + entry->addr = addr; + entry->ap_name = strdup(ap_name); + if (entry->ap_name == NULL) + return NULL; + + return entry; +} + +static void dir_entry_destroy(struct dir_entry * entry) +{ + if (entry == NULL) + return; + + free(entry->ap_name); + free(entry); +} + +struct ipcp_data * ipcp_data_create() +{ + struct ipcp_data * data = malloc(sizeof *data); + if (data == NULL) + return NULL; + + data->iname = NULL; + data->type = 0; + data->dum = NULL; + + return data; +} + +struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, + instance_name_t * iname, + enum ipcp_type ipcp_type) +{ + if (dst == NULL) + return NULL; + + dst->iname = instance_name_dup(iname); + dst->type = ipcp_type; + + dst->dum = shm_du_map_open(); + if (dst->dum == NULL) + return NULL; + + /* init the lists */ + INIT_LIST_HEAD(&dst->registry); + INIT_LIST_HEAD(&dst->flows); + INIT_LIST_HEAD(&dst->directory); + + /* init the mutexes */ + pthread_mutex_init(&dst->reg_lock, NULL); + pthread_mutex_init(&dst->dir_lock, NULL); + pthread_mutex_init(&dst->flow_lock, NULL); + + return dst; +} + +static void clear_registry(struct ipcp_data * data) +{ + struct list_head * h; + struct list_head * t; + list_for_each_safe(h, t, &data->registry) + reg_entry_destroy(list_entry(h, struct reg_entry, list)); +} + +static void clear_directory(struct ipcp_data * data) +{ + struct list_head * h; + struct list_head * t; + list_for_each_safe(h, t, &data->directory) + dir_entry_destroy(list_entry(h, struct dir_entry, list)); +} + +static void clear_flows(struct ipcp_data * data) +{ + struct list_head * h; + struct list_head * t; + list_for_each_safe(h, t, &data->flows) + flow_destroy(list_entry(h, flow_t, list)); + +} + +void ipcp_data_destroy(struct ipcp_data * data) +{ + if (data == NULL) + return; + + /* FIXME: finish all pending operations here */ + + if (data->iname != NULL) + instance_name_destroy(data->iname); + data->iname = NULL; + + if (data->dum != NULL) + shm_du_map_close(data->dum); + data->dum = NULL; + + pthread_mutex_lock(&data->reg_lock); + pthread_mutex_lock(&data->dir_lock); + pthread_mutex_lock(&data->flow_lock); + + /* clear the lists */ + clear_registry(data); + clear_directory(data); + clear_flows(data); + + /* no need to unlock, just free the entire thing + pthread_mutex_unlock(&data->flow_lock); + pthread_mutex_unlock(&data->dir_lock); + pthread_mutex_unlock(&data->reg_lock); + */ + + free(data); +} + + + +static struct reg_entry * find_reg_entry_by_name(struct ipcp_data * data, + const char * ap_name) +{ + struct list_head * h; + list_for_each(h, &data->registry) { + struct reg_entry * e = list_entry(h, struct reg_entry, list); + if (!strcmp(e->ap_name, ap_name)) + return e; + } + + return NULL; +} + +static struct reg_entry * find_reg_entry_by_id(struct ipcp_data * data, + uint32_t reg_ap_id) +{ + struct list_head * h; + list_for_each(h, &data->registry) { + struct reg_entry * e = list_entry(h, struct reg_entry, list); + if (e->reg_ap_id == reg_ap_id) + return e; + } + + return NULL; +} + +static struct dir_entry * find_dir_entry(struct ipcp_data * data, + const char * ap_name, + uint64_t addr) +{ + struct list_head * h; + list_for_each(h, &data->directory) { + struct dir_entry * e = list_entry(h, struct dir_entry, list); + if (e->addr == addr && !strcmp(e->ap_name, ap_name)) + return e; + } + + return NULL; +} + +static struct dir_entry * find_dir_entry_any(struct ipcp_data * data, + const char * ap_name) +{ + struct list_head * h; + list_for_each(h, &data->directory) { + struct dir_entry * e = list_entry(h, struct dir_entry, list); + if (!strcmp(e->ap_name, ap_name)) + return e; + } + + return NULL; +} + +bool ipcp_data_is_in_directory(struct ipcp_data * data, + const char * ap_name) +{ + return find_dir_entry_any(data, ap_name) != NULL; +} + +int ipcp_data_del_reg_entry(struct ipcp_data * data, + uint32_t reg_ap_id) +{ + struct reg_entry * e; + if (data == NULL) + return -1; + + pthread_mutex_lock(&data->reg_lock); + + e = find_reg_entry_by_id(data, reg_ap_id); + if (e == NULL) { + pthread_mutex_unlock(&data->reg_lock); + return 0; /* nothing to do */ + } + + list_del(&e->list); + + reg_entry_destroy(e); + + pthread_mutex_unlock(&data->reg_lock); + + return 0; +} + +int ipcp_data_del_dir_entry(struct ipcp_data * data, + const char * ap_name, + uint64_t addr) +{ + struct dir_entry * e; + if (data == NULL) + return -1; + + pthread_mutex_lock(&data->dir_lock); + + e = find_dir_entry(data, ap_name, addr); + if (e == NULL) { + pthread_mutex_unlock(&data->dir_lock); + return 0; /* nothing to do */ + } + + list_del(&e->list); + + dir_entry_destroy(e); + + pthread_mutex_unlock(&data->dir_lock); + + return 0; +} + +int ipcp_data_add_reg_entry(struct ipcp_data * data, + char * ap_name, + uint32_t reg_ap_id) +{ + struct reg_entry * entry; + + if (data == NULL || ap_name == NULL) + return -1; + + pthread_mutex_lock(&data->reg_lock); + + if (find_reg_entry_by_name(data, ap_name) || + find_reg_entry_by_id(data, reg_ap_id)) { + pthread_mutex_unlock(&data->reg_lock); + return -2; + } + + entry = reg_entry_create(ap_name, reg_ap_id); + if (entry == NULL) { + pthread_mutex_unlock(&data->reg_lock); + return -1; + } + + list_add(&entry->list,&data->registry); + + pthread_mutex_unlock(&data->reg_lock); + + return 0; +} + +int ipcp_data_add_dir_entry(struct ipcp_data * data, + char * ap_name, + uint64_t addr) +{ + struct dir_entry * entry; + + if (data == NULL || ap_name == NULL) + return -1; + + pthread_mutex_lock(&data->dir_lock); + + if (find_dir_entry(data, ap_name, addr) != NULL) { + pthread_mutex_unlock(&data->dir_lock); + return -2; + } + + entry = dir_entry_create(ap_name, addr); + if (entry == NULL) { + pthread_mutex_unlock(&data->dir_lock); + return -1; + } + + list_add(&entry->list,&data->directory); + + pthread_mutex_unlock(&data->dir_lock); + + return 0; +} + +bool ipcp_data_is_in_registry(struct ipcp_data * data, + const char * ap_name) +{ + return find_reg_entry_by_name(data, ap_name) != NULL; +} + +uint32_t ipcp_data_get_reg_ap_id(struct ipcp_data * data, + const char * ap_name) +{ + struct reg_entry * entry; + uint32_t id; + + pthread_mutex_lock(&data->reg_lock); + + entry = find_reg_entry_by_name(data, ap_name); + + if (entry == NULL) { + pthread_mutex_unlock(&data->reg_lock); + return 0; /* undefined behaviour */ + } + + id = entry->reg_ap_id; + + pthread_mutex_unlock(&data->reg_lock); + + return id; +} + +const char * ipcp_data_get_reg_ap_name(struct ipcp_data * data, + uint32_t reg_ap_id) +{ + struct reg_entry * entry; + char * name; + + pthread_mutex_lock(&data->reg_lock); + + entry = find_reg_entry_by_id(data, reg_ap_id); + + if (entry == NULL) { + pthread_mutex_unlock(&data->reg_lock); + return NULL; + } + + name = strdup(entry->ap_name); + if (name == NULL) { + pthread_mutex_unlock(&data->reg_lock); + return NULL; + } + + pthread_mutex_unlock(&data->reg_lock); + + return name; +} + +uint64_t ipcp_data_get_addr(struct ipcp_data * data, + const char * ap_name) +{ + struct dir_entry * entry; + uint64_t addr; + + pthread_mutex_lock(&data->dir_lock); + + entry = find_dir_entry_any(data, ap_name); + + if (entry == NULL) { + pthread_mutex_unlock(&data->dir_lock); + return 0; /* undefined behaviour, 0 may be a valid address */ + } + + addr = entry->addr; + + pthread_mutex_unlock(&data->dir_lock); + + return addr; +} + +static flow_t * find_flow(struct ipcp_data * data, + uint32_t port_id) +{ + struct list_head * h; + list_for_each(h, &data->flows) { + flow_t * f = list_entry(h, flow_t, list); + if (f->port_id == port_id) + return f; + } + + return NULL; +} + +bool ipcp_data_has_flow(struct ipcp_data * data, + uint32_t port_id) +{ + return find_flow(data, port_id) != NULL; +} + +int ipcp_data_add_flow(struct ipcp_data * data, + flow_t * flow) +{ + if (data == NULL || flow == NULL) + return -1; + + pthread_mutex_lock(&data->flow_lock); + + if (ipcp_data_has_flow(data, flow->port_id)) { + pthread_mutex_unlock(&data->flow_lock); + return -2; + } + + list_add(&flow->list,&data->flows); + + pthread_mutex_unlock(&data->flow_lock); + + return 0; +} diff --git a/src/ipcpd/ipcp-data.h b/src/ipcpd/ipcp-data.h new file mode 100644 index 00000000..d51f3730 --- /dev/null +++ b/src/ipcpd/ipcp-data.h @@ -0,0 +1,91 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Utitilies for building IPC processes + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef IPCPD_IPCP_DATA_H +#define IPCPD_IPCP_DATA_H + +#include +#include +#include +#include +#include +#include + +#include "ipcp-ops.h" + +struct ipcp_data { + instance_name_t * iname; + enum ipcp_type type; + + struct shm_du_map * dum; + + struct list_head registry; + pthread_mutex_t reg_lock; + + struct list_head flows; + pthread_mutex_t flow_lock; + + struct list_head directory; + pthread_mutex_t dir_lock; + + pthread_mutex_t lock; +}; + +struct ipcp_data * ipcp_data_create(); +struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, + instance_name_t * iname, + enum ipcp_type ipcp_type); +void ipcp_data_destroy(struct ipcp_data * data); + +int ipcp_data_add_reg_entry(struct ipcp_data * data, + char * ap_name, + uint32_t reg_ap_id); +int ipcp_data_del_reg_entry(struct ipcp_data * data, + uint32_t reg_ap_id); +int ipcp_data_add_dir_entry(struct ipcp_data * data, + char * ap_name, + uint64_t addr); +int ipcp_data_del_dir_entry(struct ipcp_data * data, + const char * ap_name, + uint64_t addr); +bool ipcp_data_is_in_registry(struct ipcp_data * data, + const char * ap_name); +uint32_t ipcp_data_get_reg_ap_id(struct ipcp_data * data, + const char * ap_name); +const char * ipcp_data_get_reg_ap_name(struct ipcp_data * data, + uint32_t reg_ap_id); +bool ipcp_data_is_in_directory(struct ipcp_data * data, + const char * ap_name); +uint64_t ipcp_data_get_addr(struct ipcp_data * data, + const char * ap_name); +bool ipcp_data_has_flow(struct ipcp_data * data, + uint32_t port_id); +bool ipcp_data_has_flow_s(struct ipcp_data * data, + uint32_t port_id, + enum flow_state state); +int ipcp_data_add_flow(struct ipcp_data * data, + flow_t * flow); +int ipcp_data_remove_flow(struct ipcp_data * data, + uint32_t port_id); + +#endif /* IPCPD_IPCP_DATA_H */ diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h new file mode 100644 index 00000000..69682739 --- /dev/null +++ b/src/ipcpd/ipcp-ops.h @@ -0,0 +1,59 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process ops + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef IPCPD_IPCP_OPS_H +#define IPCPD_IPCP_OPS_H + +#include +#include +#include + +struct ipcp_ops { + int (* ipcp_bootstrap)(struct dif_config * conf); + int (* ipcp_enroll)(char * member_name, + char * n_1_dif); + int (* ipcp_reg)(char ** dif_names, + size_t len); + int (* ipcp_unreg)(char ** dif_names, + size_t len); + int (* ipcp_ap_reg)(char * ap_name, + uint32_t reg_ap_id); + int (* ipcp_ap_unreg)(uint32_t reg_ap_id); + int (* ipcp_flow_alloc)(uint32_t port_id, + char * dst_ap_name, + char * src_ap_name, + char * src_ae_name, + struct qos_spec * qos); + int (* ipcp_flow_alloc_resp)(uint32_t port_id, + int result); + int (* ipcp_flow_dealloc)(uint32_t port_id); + + /* FIXME: let's see how this will work with the shm_du_map */ + int (* ipcp_du_write)(uint32_t port_id, + size_t map_index); + + int (* ipcp_du_read)(uint32_t port_id, + size_t map_index); +}; + +#endif /* IPCPD_IPCP_OPS_H */ diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c new file mode 100644 index 00000000..a1276769 --- /dev/null +++ b/src/ipcpd/ipcp.c @@ -0,0 +1,195 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process main loop + * + * Dimitri Staessens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include "ipcp.h" + +#define OUROBOROS_PREFIX "ipcpd/ipcp" +#include + +int ipcp_main_loop(struct ipcp * _ipcp) +{ + int lsockfd; + int sockfd; + uint8_t buf[IPCP_MSG_BUF_SIZE]; + + ipcp_msg_t * msg; + ssize_t count; + buffer_t buffer; + ipcp_msg_t ret_msg = IPCP_MSG__INIT; + + dif_config_msg_t * conf_msg; + struct dif_config conf; + + if (_ipcp == NULL) { + LOG_ERR("Invalid ipcp struct."); + return 1; + } + + sockfd = server_socket_open(ipcp_sock_path(getpid())); + if (sockfd < 0) { + LOG_ERR("Could not open server socket."); + return 1; + } + + while (true) { + ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY; + + lsockfd = accept(sockfd, 0, 0); + if (lsockfd < 0) { + LOG_ERR("Cannot accept new connection"); + break; + } + + count = read(lsockfd, buf, IPCP_MSG_BUF_SIZE); + if (count <= 0) { + LOG_ERR("Failed to read from socket"); + close(lsockfd); + continue; + } + + msg = ipcp_msg__unpack(NULL, count, buf); + if (msg == NULL) { + close(lsockfd); + continue; + } + + switch (msg->code) { + case IPCP_MSG_CODE__IPCP_BOOTSTRAP: + conf_msg = msg->conf; + conf.type = conf_msg->ipcp_type; + if (conf_msg->ipcp_type == IPCP_NORMAL) { + conf.addr_size = conf_msg->addr_size; + conf.cep_id_size = conf_msg->cep_id_size; + conf.pdu_length_size + = conf_msg->pdu_length_size; + conf.qos_id_size = conf_msg->qos_id_size; + conf.seqno_size = conf_msg->seqno_size; + conf.ttl_size = conf_msg->seqno_size; + conf.chk_size = conf_msg->chk_size; + conf.min_pdu_size = conf_msg->min_pdu_size; + conf.max_pdu_size = conf_msg->max_pdu_size; + } + if (conf_msg->ipcp_type == IPCP_SHIM_UDP) { + conf.ip_addr = conf_msg->ip_addr; + conf.dns_addr = conf_msg->dns_addr; + } + + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_bootstrap(&conf); + break; + case IPCP_MSG_CODE__IPCP_ENROLL: + if (_ipcp->ops->ipcp_enroll == NULL) { + LOG_ERR("ipcp_enroll unsupported."); + } else { + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_enroll( + msg->member_name, msg->n_1_dif); + } + break; + + case IPCP_MSG_CODE__IPCP_REG: + if (_ipcp->ops->ipcp_reg == NULL) { + LOG_ERR("ipcp_reg unsupported."); + + } else { + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_reg( + msg->dif_names, msg->len); + } + break; + case IPCP_MSG_CODE__IPCP_UNREG: + if (_ipcp->ops->ipcp_unreg == NULL) { + LOG_ERR("ipcp_unreg unsupported."); + + } else { + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_unreg( + msg->dif_names, msg->len); + } + break; + case IPCP_MSG_CODE__IPCP_AP_REG: + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_ap_reg( + msg->ap_name, msg->reg_ap_id); + break; + case IPCP_MSG_CODE__IPCP_AP_UNREG: + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_ap_unreg( + msg->reg_ap_id); + break; + case IPCP_MSG_CODE__IPCP_FLOW_ALLOC: + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_flow_alloc( + msg->port_id, + msg->dst_ap_name, + msg->ap_name, + msg->ae_name, + NULL); + break; + case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_flow_alloc_resp( + msg->port_id, msg->result); + break; + case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC: + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_flow_dealloc( + msg->port_id); + break; + default: + LOG_ERR("Don't know that message code"); + break; + } + + ipcp_msg__free_unpacked(msg, NULL); + + buffer.size = ipcp_msg__get_packed_size(&ret_msg); + if (buffer.size == 0) { + LOG_ERR("Failed to send reply message"); + close(lsockfd); + continue; + } + + buffer.data = malloc(buffer.size); + if (buffer.data == NULL) { + close(lsockfd); + continue; + } + + ipcp_msg__pack(&ret_msg, buffer.data); + + if (write(lsockfd, buffer.data, buffer.size) == -1) { + free(buffer.data); + close(lsockfd); + continue; + } + + free(buffer.data); + close(lsockfd); + } + + return 0; +} diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h new file mode 100644 index 00000000..d6ddeb43 --- /dev/null +++ b/src/ipcpd/ipcp.h @@ -0,0 +1,48 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process structure + * + * Dimitri Staessens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef IPCPD_IPCP_H +#define IPCPD_IPCP_H + +#include "ipcp-ops.h" +#include "ipcp-data.h" + +enum ipcp_state { + IPCP_INIT = 0, + IPCP_ENROLLING, + IPCP_BOOTSTRAPPING, + IPCP_ENROLLED, + IPCP_DISCONNECTED, + IPCP_SHUTDOWN +}; + +struct ipcp { + struct ipcp_data * data; + struct ipcp_ops * ops; + + enum ipcp_state state; + int irmd_fd; +}; + +int ipcp_main_loop(); + +#endif diff --git a/src/ipcpd/main.c b/src/ipcpd/main.c deleted file mode 100644 index 7ffd1c48..00000000 --- a/src/ipcpd/main.c +++ /dev/null @@ -1,15 +0,0 @@ -#define OUROBOROS_PREFIX "ipcp" - -#include -#include - -int main() -{ - LOG_DBG("Test of the IPCP"); - - while (true) { - - } - - return 0; -} diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt new file mode 100644 index 00000000..c13cbaa3 --- /dev/null +++ b/src/ipcpd/normal/CMakeLists.txt @@ -0,0 +1,32 @@ +get_filename_component(CURRENT_SOURCE_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(CURRENT_BINARY_PARENT_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CURRENT_SOURCE_PARENT_DIR}) +include_directories(${CURRENT_BINARY_PARENT_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +SET(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET") + +set(SOURCE_FILES + # Add source files here + main.c + pci.c +) + +add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES}) +target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros) + +include(MacroAddCompileFlags) +if (CMAKE_BUILD_TYPE MATCHES Debug) + MACRO_ADD_COMPILE_FLAGS(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) +endif (CMAKE_BUILD_TYPE MATCHES Debug) + +install(TARGETS ipcpd-normal RUNTIME DESTINATION bin) + +# Enable once ipcp-normal has tests +# add_subdirectory(tests) diff --git a/src/ipcpd/normal/dt_const.h b/src/ipcpd/normal/dt_const.h new file mode 100644 index 00000000..bc0c1466 --- /dev/null +++ b/src/ipcpd/normal/dt_const.h @@ -0,0 +1,44 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Data Transfer Constants for the IPCP + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef IPCP_DT_CONST_H +#define IPCP_DT_CONST_H + +#include "ouroboros/common.h" + +struct ipcp_dtp_const { + /* sizes in octets */ + uint8_t addr_size; + uint8_t cep_id_size; + uint8_t pdu_length_size; + uint8_t seqno_size; + uint8_t qos_id_size; + /* uint8_t ctrl_sqnum_sz; is this in the spec?? */ +}; + +struct ipcp_dup_const { + uint8_t ttl_size; + uint8_t chk_size; +}; + +#endif /* IPCP_DT_CONST_H */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c new file mode 100644 index 00000000..7ffd1c48 --- /dev/null +++ b/src/ipcpd/normal/main.c @@ -0,0 +1,15 @@ +#define OUROBOROS_PREFIX "ipcp" + +#include +#include + +int main() +{ + LOG_DBG("Test of the IPCP"); + + while (true) { + + } + + return 0; +} diff --git a/src/ipcpd/normal/pci.c b/src/ipcpd/normal/pci.c new file mode 100644 index 00000000..d7df52b6 --- /dev/null +++ b/src/ipcpd/normal/pci.c @@ -0,0 +1,146 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Protocol Control Information + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "pci.h" +#include +#include + +#define OUROBOROS_PREFIX "ipcp/pci" + +#include + +#define PCI_HEAD_SIZE(a, b) a.addr_size * 2 + \ + a.cep_id_size * 2 + \ + a.pdu_length_size + \ + b.ttl_size + \ + a.seqno_size + \ + a.qos_id_size +#define PCI_TAIL_SIZE(b) b.chk_size + + +struct pci { + /* head */ + uint8_t * dst_addr; + uint8_t * src_addr; + uint8_t * dst_cep_id; + uint8_t * src_cep_id; + uint8_t * pdu_length; + uint8_t * ttl; + uint8_t * seqno; + uint8_t * qos_id; + + uint8_t * chk; + + du_buff_t * dub; + + struct ipcp_dtp_const dtpc; + struct ipcp_dup_const dupc; + +}; + +pci_t * pci_create(du_buff_t * dub, + const struct ipcp_dtp_const * dtpc, + const struct ipcp_dup_const * dupc) +{ + struct pci * p; + + if (dub == NULL) { + LOG_DBGF("Bogus input. Bugging out."); + return NULL; + } + + p = malloc(sizeof *p); + + if (p == NULL) + return NULL; + + p->dub = dub; + + p->dtpc = *dtpc; + p->dupc = *dupc; + + p->dst_addr = NULL; + p->src_addr = NULL; + p->dst_cep_id = NULL; + p->src_cep_id = NULL; + p->pdu_length = NULL; + p->ttl = NULL; + p->seqno = NULL; + p->qos_id = NULL; + p->chk = NULL; + + return p; +} + +void pci_destroy(pci_t * pci) +{ + free(pci); +} + +int pci_init(pci_t * pci) +{ + if (pci == NULL) { + LOG_DBGF("Bogus input. Bugging out."); + return -EINVAL; + } + + uint8_t * pci_head = du_buff_head_alloc(pci->dub, PCI_HEAD_SIZE( + pci->dtpc,pci->dupc)); + uint8_t * pci_tail = du_buff_tail_alloc(pci->dub, PCI_TAIL_SIZE( + pci->dupc)); + + if (pci_head == NULL) { + LOG_DBG("Failed to allocate space for PCI at head."); + return -ENOBUFS; + } + + if (pci_tail == NULL) { + LOG_DBG("Failed to allocate space for PCI at tail."); + return -ENOBUFS; + } + + pci->dst_addr = pci_head; + pci->src_addr = (pci_head += pci->dtpc.addr_size); + pci->dst_cep_id = (pci_head += pci->dtpc.addr_size); + pci->src_cep_id = (pci_head += pci->dtpc.cep_id_size); + pci->pdu_length = (pci_head += pci->dtpc.cep_id_size); + pci->ttl = (pci_head += pci->dtpc.pdu_length_size); + pci->seqno = (pci_head += pci->dupc.ttl_size); + pci->qos_id = (pci_head += pci->dtpc.seqno_size); + + pci->chk = (pci_tail); + + return 0; +} + +void pci_release(pci_t * pci) +{ + if (pci == NULL) + return; + + if (pci->dub == NULL) + return; + + du_buff_head_release(pci->dub, PCI_HEAD_SIZE(pci->dtpc, pci->dupc)); + du_buff_tail_release(pci->dub, PCI_TAIL_SIZE(pci->dupc)); +} diff --git a/src/ipcpd/normal/pci.h b/src/ipcpd/normal/pci.h new file mode 100644 index 00000000..3c011723 --- /dev/null +++ b/src/ipcpd/normal/pci.h @@ -0,0 +1,42 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Protocol Control Information + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCP_PCI_H +#define OUROBOROS_IPCP_PCI_H + +#include "ouroboros/du_buff.h" +#include "dt_const.h" + +struct pci; + +typedef struct pci pci_t; + +pci_t * pci_create(du_buff_t * dub, + const struct ipcp_dtp_const * dtpc, + const struct ipcp_dup_const * dupc); +void pci_destroy(pci_t * pci); + +int pci_init(pci_t * pci); +void pci_release(pci_t * pci); + +#endif /* OUROBOROS_IPCP_PCI_H */ diff --git a/src/ipcpd/normal/shm_pci.c b/src/ipcpd/normal/shm_pci.c new file mode 100644 index 00000000..e76d8009 --- /dev/null +++ b/src/ipcpd/normal/shm_pci.c @@ -0,0 +1,146 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Protocol Control Information in Shared Memory Map + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "shm_pci.h" +#include +#include + +#define SHM_PCI_HEAD_SIZE(a, b) a.addr_size * 2 + \ + a.cep_id_size * 2 + \ + a.pdu_length_size + \ + b.ttl_size + \ + a.seqno_size + \ + a.qos_id_size +#define SHM_PCI_TAIL_SIZE(b) b.chk_size + +#define OUROBOROS_PREFIX "ipcpd/shm_pci" + +#include + +struct shm_pci { + /* head */ + uint8_t * dst_addr; + uint8_t * src_addr; + uint8_t * dst_cep_id; + uint8_t * src_cep_id; + uint8_t * pdu_length; + uint8_t * ttl; + uint8_t * seqno; + uint8_t * qos_id; + + uint8_t * chk; + + struct shm_du_buff * dub; + + struct ipcp_dtp_const dtpc; + struct ipcp_dup_const dupc; + +}; + +shm_pci_t * shm_pci_create(struct shm_du_buff * dub, + const struct ipcp_dtp_const * dtpc, + const struct ipcp_dup_const * dupc) +{ + struct shm_pci * p; + + if (dub == NULL) { + LOG_DBGF("Bogus input. Bugging out."); + return NULL; + } + + p = malloc(sizeof *p); + + if (p == NULL) + return NULL; + + p->dub = dub; + + p->dtpc = *dtpc; + p->dupc = *dupc; + + p->dst_addr = NULL; + p->src_addr = NULL; + p->dst_cep_id = NULL; + p->src_cep_id = NULL; + p->pdu_length = NULL; + p->ttl = NULL; + p->seqno = NULL; + p->qos_id = NULL; + p->chk = NULL; + + return p; +} + +void shm_pci_destroy(shm_pci_t * pci) +{ + free(pci); +} + +int shm_pci_init(shm_pci_t * pci) +{ + if (pci == NULL) { + LOG_DBGF("Bogus input. Bugging out."); + return -EINVAL; + } + + uint8_t * pci_head = shm_du_buff_head_alloc( + pci->dub, SHM_PCI_HEAD_SIZE(pci->dtpc, pci->dupc)); + uint8_t * pci_tail = shm_du_buff_tail_alloc( + pci->dub, SHM_PCI_TAIL_SIZE(pci->dupc)); + + if (pci_head == NULL) { + LOG_DBG("Failed to allocate space for PCI at head."); + return -ENOBUFS; + } + + if (pci_tail == NULL) { + LOG_DBG("Failed to allocate space for PCI at tail."); + return -ENOBUFS; + } + + pci->dst_addr = pci_head; + pci->src_addr = (pci_head += pci->dtpc.addr_size); + pci->dst_cep_id = (pci_head += pci->dtpc.addr_size); + pci->src_cep_id = (pci_head += pci->dtpc.cep_id_size); + pci->pdu_length = (pci_head += pci->dtpc.cep_id_size); + pci->ttl = (pci_head += pci->dtpc.pdu_length_size); + pci->seqno = (pci_head += pci->dupc.ttl_size); + pci->qos_id = (pci_head += pci->dtpc.seqno_size); + + pci->chk = (pci_tail); + + return 0; +} + +void shm_pci_release(shm_pci_t * pci) +{ + if (pci == NULL) + return; + + if (pci->dub == NULL) + return; + + shm_du_buff_head_release(pci->dub, SHM_PCI_HEAD_SIZE(pci->dtpc, + pci->dupc)); + shm_du_buff_tail_release(pci->dub, SHM_PCI_TAIL_SIZE(pci->dupc)); +} diff --git a/src/ipcpd/normal/shm_pci.h b/src/ipcpd/normal/shm_pci.h new file mode 100644 index 00000000..cb8dd5dd --- /dev/null +++ b/src/ipcpd/normal/shm_pci.h @@ -0,0 +1,43 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Protocol Control Information in Shared Memory Map + * + * Dimitri Staessens + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCP_SHM_PCI_H +#define OUROBOROS_IPCP_SHM_PCI_H + +#include + +#include + +struct shm_pci; + +typedef struct shm_pci shm_pci_t; + +shm_pci_t * shm_pci_create(struct shm_du_buff * dub, + const struct ipcp_dtp_const * dtpc, + const struct ipcp_dup_const * dupc); +void shm_pci_destroy(shm_pci_t * pci); + +int shm_pci_init(shm_pci_t * pci); +void shm_pci_release(shm_pci_t * pci); + +#endif /* OUROBOROS_IPCP_SHM_PCI_H */ diff --git a/src/ipcpd/pci.c b/src/ipcpd/pci.c deleted file mode 100644 index 548e40e2..00000000 --- a/src/ipcpd/pci.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Protocol Control Information - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "pci.h" -#include -#include - -#define OUROBOROS_PREFIX "ipcp/pci" - -#include - -#define PCI_HEAD_SIZE(a, b) a.addr_size * 2 + \ - a.cep_id_size * 2 + \ - a.pdu_length_size + \ - b.ttl_size + \ - a.seqno_size + \ - a.qos_id_size -#define PCI_TAIL_SIZE(b) b.chk_size - - -struct pci { - /* head */ - uint8_t * dst_addr; - uint8_t * src_addr; - uint8_t * dst_cep_id; - uint8_t * src_cep_id; - uint8_t * pdu_length; - uint8_t * ttl; - uint8_t * seqno; - uint8_t * qos_id; - - uint8_t * chk; - - du_buff_t * dub; - - struct ipcp_dtp_const dtpc; - struct ipcp_dup_const dupc; - -}; - -pci_t * pci_create(du_buff_t * dub, - const struct ipcp_dtp_const * dtpc, - const struct ipcp_dup_const * dupc) -{ - struct pci * p; - - if (dub == NULL) { - LOG_DBGF("Bogus input. Bugging out."); - return NULL; - } - - p = malloc(sizeof *p); - - if (p == NULL) - return NULL; - - p->dub = dub; - - p->dtpc = *dtpc; - p->dupc = *dupc; - - p->dst_addr = NULL; - p->src_addr = NULL; - p->dst_cep_id = NULL; - p->src_cep_id = NULL; - p->pdu_length = NULL; - p->ttl = NULL; - p->seqno = NULL; - p->qos_id = NULL; - p->chk = NULL; - - return p; -} - -void pci_destroy(pci_t * pci) -{ - free(pci); -} - -int pci_init(pci_t * pci) -{ - if (pci == NULL) { - LOG_DBGF("Bogus input. Bugging out."); - return -EINVAL; - } - - uint8_t * pci_head = du_buff_head_alloc(pci->dub, PCI_HEAD_SIZE( - pci->dtpc,pci->dupc)); - uint8_t * pci_tail = du_buff_tail_alloc(pci->dub, PCI_TAIL_SIZE( - pci->dupc)); - - if (pci_head == NULL) { - LOG_DBG("Failed to allocate space for PCI at head."); - return -ENOBUFS; - } - - if (pci_tail == NULL) { - LOG_DBG("Failed to allocate space for PCI at tail."); - return -ENOBUFS; - } - - pci->dst_addr = pci_head; - pci->src_addr = (pci_head += pci->dtpc.addr_size); - pci->dst_cep_id = (pci_head += pci->dtpc.addr_size); - pci->src_cep_id = (pci_head += pci->dtpc.cep_id_size); - pci->pdu_length = (pci_head += pci->dtpc.cep_id_size); - pci->ttl = (pci_head += pci->dtpc.pdu_length_size); - pci->seqno = (pci_head += pci->dupc.ttl_size); - pci->qos_id = (pci_head += pci->dtpc.seqno_size); - - pci->chk = (pci_tail); - - return 0; -} - -void pci_release(pci_t * pci) -{ - if (pci == NULL) - return; - - if (pci->dub == NULL) - return; - - du_buff_head_release(pci->dub, PCI_HEAD_SIZE(pci->dtpc, pci->dupc)); - du_buff_tail_release(pci->dub, PCI_TAIL_SIZE(pci->dupc)); -} diff --git a/src/ipcpd/pci.h b/src/ipcpd/pci.h deleted file mode 100644 index 3c011723..00000000 --- a/src/ipcpd/pci.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Protocol Control Information - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef OUROBOROS_IPCP_PCI_H -#define OUROBOROS_IPCP_PCI_H - -#include "ouroboros/du_buff.h" -#include "dt_const.h" - -struct pci; - -typedef struct pci pci_t; - -pci_t * pci_create(du_buff_t * dub, - const struct ipcp_dtp_const * dtpc, - const struct ipcp_dup_const * dupc); -void pci_destroy(pci_t * pci); - -int pci_init(pci_t * pci); -void pci_release(pci_t * pci); - -#endif /* OUROBOROS_IPCP_PCI_H */ diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt new file mode 100644 index 00000000..27907880 --- /dev/null +++ b/src/ipcpd/shim-udp/CMakeLists.txt @@ -0,0 +1,31 @@ +get_filename_component(CURRENT_SOURCE_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(CURRENT_BINARY_PARENT_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CURRENT_SOURCE_PARENT_DIR}) +include_directories(${CURRENT_BINARY_PARENT_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") + +set(SHIM_UDP_SOURCES + # Add source files here + ${CMAKE_CURRENT_SOURCE_DIR}/main.c +) + +add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES}) +target_link_libraries (ipcpd-shim-udp LINK_PUBLIC ouroboros) + +include(MacroAddCompileFlags) +if (CMAKE_BUILD_TYPE MATCHES Debug) + MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG) +endif (CMAKE_BUILD_TYPE MATCHES Debug) + +install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION bin) + +# Enable once ipcp-shim-udp has tests +add_subdirectory(tests) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c new file mode 100644 index 00000000..1fb12dc0 --- /dev/null +++ b/src/ipcpd/shim-udp/main.c @@ -0,0 +1,323 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Shim IPC process over UDP + * + * Dimitri Staessens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "ipcp.h" +#include +#include +#include +#include +#include +#include + +#define OUROBOROS_PREFIX "ipcpd/shim-udp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define THIS_TYPE IPCP_SHIM_UDP + +#define shim_data(type) ((struct ipcp_udp_data *) type->data) + +/* global for trapping signal */ +int irmd_pid; + +/* this IPCP's data */ +#ifdef MAKE_CHECK +extern struct ipcp * _ipcp; /* defined in test */ +#else +struct ipcp * _ipcp; +#endif + +struct ipcp_udp_data { + /* IPCP_DATA STRUCT MUST BE FIRST!! */ + struct ipcp_data ipcp_data; + + uint32_t ip_addr; + uint32_t dns_addr; + + pthread_mutex_t lock; +}; + +struct udp_flow { + /* FLOW MUST BE FIRST !!!! */ + flow_t flow; + + uint16_t localport; + + struct sockaddr_in * remote; + int fd; +}; + +void ipcp_sig_handler(int sig, siginfo_t * info, void * c) +{ + switch(sig) { + case SIGINT: + case SIGTERM: + case SIGHUP: + LOG_DBG("Terminating by order of %d. Bye.", info->si_pid); + if (info->si_pid == irmd_pid) { + shm_du_map_close(_ipcp->data->dum); + exit(0); + } + default: + return; + } +} + +struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, + char * ap_id) +{ + struct ipcp_udp_data * udp_data; + struct ipcp_data * data; + instance_name_t * instance_name; + enum ipcp_type ipcp_type; + + instance_name = instance_name_create(); + if (instance_name == NULL) { + LOG_ERR("Failed to create instance name struct."); + return NULL; + } + + instance_name = instance_name_init_with( + instance_name, ap_name, (uint16_t)atoi(ap_id)); + + if (instance_name == NULL) { + LOG_ERR("Failed to create instance name struct."); + return NULL; + } + + udp_data= malloc (sizeof *udp_data); + if (udp_data == NULL) { + LOG_DBGF("Failed to allocate."); + return NULL; + } + + ipcp_type = THIS_TYPE; + data = (struct ipcp_data *) udp_data; + if (ipcp_data_init(data, instance_name, ipcp_type) == NULL) { + free(udp_data); + return NULL; + } + + return udp_data; +} + +int ipcp_udp_bootstrap(struct dif_config * conf) +{ + char ipstr[INET_ADDRSTRLEN]; + char dnsstr[INET_ADDRSTRLEN]; + + if (conf->type != THIS_TYPE) { + LOG_ERR("Config doesn't match IPCP type."); + return -1; + } + + if (_ipcp->state != IPCP_INIT) { + LOG_ERR("IPCP in wrong state."); + return -1; + } + + inet_ntop(AF_INET, + &conf->ip_addr, + ipstr, + INET_ADDRSTRLEN); + + if (conf->dns_addr != 0) + inet_ntop(AF_INET, + &conf->dns_addr, + dnsstr, + INET_ADDRSTRLEN); + else + strcpy(dnsstr, "not set"); + + shim_data(_ipcp)->ip_addr = conf->ip_addr; + shim_data(_ipcp)->dns_addr = conf->dns_addr; + + _ipcp->state = IPCP_ENROLLED; + + LOG_DBG("Bootstrapped shim IPCP over UDP %s-%d.", + _ipcp->data->iname->name, _ipcp->data->iname->id); + + LOG_DBG("Bound to IP address %s.", ipstr); + LOG_DBG("DNS server address is %s.", dnsstr); + + return 0; +} + +int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) +{ + LOG_DBG("Registering local ap %s, %u.", ap_name, reg_ap_id); + + if (_ipcp->state != IPCP_ENROLLED) { + LOG_DBGF("Won't register with non-enrolled IPCP."); + return -1; + } + + if (ipcp_data_add_reg_entry(_ipcp->data, ap_name, reg_ap_id)) { + LOG_ERR("Failed to add AP to local registry."); + return -1; + } + + LOG_MISSING; + + return 0; +} + +int ipcp_udp_ap_unreg(uint32_t reg_ap_id) +{ + char * name = strdup(ipcp_data_get_reg_ap_name(_ipcp->data, + reg_ap_id)); + LOG_DBG("Unregistering %s.", name); + + ipcp_data_del_reg_entry(_ipcp->data, reg_ap_id); + + /* we are using dns */ + LOG_MISSING; + + free (name); + + return 0; +} + +int ipcp_udp_flow_alloc(uint32_t port_id, + char * dst_ap_name, + char * src_ap_name, + char * src_ae_name, + struct qos_spec * qos) +{ + return 0; +} +int ipcp_udp_flow_alloc_resp(uint32_t port_id, + int result) +{ + return 0; +} + +int ipcp_udp_flow_dealloc(uint32_t port_id) +{ + return 0; +} + +int ipcp_udp_du_write(uint32_t port_id, + size_t map_index) +{ + return 0; +} + +int ipcp_udp_du_read(uint32_t port_id, + size_t map_index) +{ + return 0; +} + +struct ipcp * ipcp_udp_create(char * ap_name, char * i_id) +{ + struct ipcp * i; + struct ipcp_udp_data * data; + struct ipcp_ops * ops; + + i = malloc(sizeof *i); + if (i == NULL) + return NULL; + + data = ipcp_udp_data_create(ap_name, i_id); + if (data == NULL) { + free(i); + return NULL; + } + + ops = malloc (sizeof *ops); + if (ops == NULL) { + free(data); + free(i); + return NULL; + } + + ops->ipcp_bootstrap = ipcp_udp_bootstrap; + ops->ipcp_enroll = NULL; /* shim */ + ops->ipcp_reg = NULL; /* shim */ + ops->ipcp_unreg = NULL; /* shim */ + ops->ipcp_ap_reg = ipcp_udp_ap_reg; + ops->ipcp_ap_unreg = ipcp_udp_ap_unreg; + ops->ipcp_flow_alloc = ipcp_udp_flow_alloc; + ops->ipcp_flow_alloc_resp = ipcp_udp_flow_alloc_resp; + ops->ipcp_flow_dealloc = ipcp_udp_flow_dealloc; + ops->ipcp_du_read = ipcp_udp_du_read; + ops->ipcp_du_write = ipcp_udp_du_write; + + i->data = (struct ipcp_data *) data; + i->ops = ops; + + i->state = IPCP_INIT; + + return i; +} + +#ifndef MAKE_CHECK + +int main (int argc, char * argv[]) +{ + /* argument 1: pid of irmd ? */ + /* argument 2: ap name */ + /* argument 3: instance id */ + struct sigaction sig_act; + + /* FIXME: clean up argument checks */ + if (argc != 4) + LOG_ERR("Wrong arguments passed."); + + /* store the process id of the irmd */ + irmd_pid = atoi(argv[1]); + + /* init sig_act */ + memset (&sig_act, 0, sizeof sig_act); + + /* install signal traps */ + sig_act.sa_sigaction = &ipcp_sig_handler; + sig_act.sa_flags = SA_SIGINFO; + + sigaction(SIGINT, &sig_act, NULL); + sigaction(SIGTERM, &sig_act, NULL); + sigaction(SIGHUP, &sig_act, NULL); + + _ipcp = ipcp_udp_create(argv[2], argv[3]); + if (_ipcp == NULL) { + LOG_ERR("Won't."); + exit(1); + } + + ipcp_main_loop(_ipcp); + + exit(0); +} + +#endif /* MAKE_CHECK */ diff --git a/src/ipcpd/shim-udp/tests/CMakeLists.txt b/src/ipcpd/shim-udp/tests/CMakeLists.txt new file mode 100644 index 00000000..bdd7defb --- /dev/null +++ b/src/ipcpd/shim-udp/tests/CMakeLists.txt @@ -0,0 +1,33 @@ +get_filename_component(PARENT_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(PARENT_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +get_filename_component(PARENT_DIR ${PARENT_SOURCE_PATH} NAME) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${PARENT_SOURCE_PATH}) +include_directories(${PARENT_BINARY_PATH}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +create_test_sourcelist(${PARENT_DIR}_tests test_suite.c + # Add new tests here + shim_udp_test.c +) + +add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${IPCP_SOURCES} ${${PARENT_DIR}_tests}) +target_link_libraries(${PARENT_DIR}_test ouroboros) + +include(MacroAddCompileFlags) +MACRO_ADD_COMPILE_FLAGS(${PARENT_DIR}_test -DMAKE_CHECK) + +add_dependencies(check ${PARENT_DIR}_test) + +set(tests_to_run ${${PARENT_DIR}_tests}) +remove(tests_to_run test_suite.c) + +foreach(test ${tests_to_run}) + get_filename_component(test_name ${test} NAME_WE) + add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) +endforeach(test) diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c new file mode 100644 index 00000000..427d0e1e --- /dev/null +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -0,0 +1,103 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Test of the Shim UDP IPCP Daemon + * + * Dimitri Staessens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include "main.c" + +#include + +struct ipcp * _ipcp; + +int shim_udp_test(int argc, char ** argv) +{ + /* argument 1: pid of irmd ? */ + /* argument 2: ap name */ + /* argument 3: instance id */ + struct shm_du_map * dum; + char * ipcp_name = "test-shim-ipcp"; + char * i_id = "1"; + int i = 0; + + char bogus[15]; + memset (&bogus, 0, 15); + + struct dif_config conf; + memset (&conf, 0, sizeof conf); + conf.dif_name = strdup("test-dif"); + conf.type = IPCP_SHIM_UDP; + conf.ip_addr = 0; + + dum = shm_du_map_create(); + if (dum == NULL) { + LOG_ERR("Failed to create shared memory."); + exit(1); + } + + _ipcp = ipcp_udp_create(ipcp_name, i_id); + if (_ipcp == NULL) { + LOG_ERR("Could not instantiate shim IPCP."); + shm_du_map_close(dum); + exit(1); + } + + if (ipcp_udp_bootstrap (&conf)) { + LOG_ERR("Could not bootstrap."); + } + + if(ipcp_udp_ap_reg("bogus ap", 1865)) { + LOG_ERR("Failed to register application."); + shm_du_map_close(dum); + exit(1); + } + + if (ipcp_udp_ap_unreg(1865)) { + LOG_ERR("Failed to unregister application."); + shm_du_map_close(dum); + exit(1); + } + + for (i = 0; i < 1000; ++i) { + sprintf (bogus, "bogus ap %4d", i); + if(ipcp_udp_ap_reg(bogus, i)) { + LOG_ERR("Failed to register application %s.", bogus); + shm_du_map_close(dum); + exit(1); + } + } + + for (i = 0; i < 1000; ++i) { + if(ipcp_udp_ap_unreg(i)) { + LOG_ERR("Failed to unregister application %d.", i); + shm_du_map_close(dum); + exit(1); + } + } + + shm_du_map_close(dum); + + exit(0); +} diff --git a/src/ipcpd/shm_pci.c b/src/ipcpd/shm_pci.c deleted file mode 100644 index d44e0e8f..00000000 --- a/src/ipcpd/shm_pci.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Protocol Control Information in Shared Memory Map - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "shm_pci.h" -#include -#include - -#define SHM_PCI_HEAD_SIZE(a, b) a.addr_size * 2 + \ - a.cep_id_size * 2 + \ - a.pdu_length_size + \ - b.ttl_size + \ - a.seqno_size + \ - a.qos_id_size -#define SHM_PCI_TAIL_SIZE(b) b.chk_size - -#define OUROBOROS_PREFIX "ipcpd/shm_pci" - -#include - -struct shm_pci { - /* head */ - uint8_t * dst_addr; - uint8_t * src_addr; - uint8_t * dst_cep_id; - uint8_t * src_cep_id; - uint8_t * pdu_length; - uint8_t * ttl; - uint8_t * seqno; - uint8_t * qos_id; - - uint8_t * chk; - - struct shm_du_buff * dub; - - struct ipcp_dtp_const dtpc; - struct ipcp_dup_const dupc; - -}; - -shm_pci_t * shm_pci_create(struct shm_du_buff * dub, - const struct ipcp_dtp_const * dtpc, - const struct ipcp_dup_const * dupc) -{ - struct shm_pci * p; - - if (dub == NULL) { - LOG_DBGF("Bogus input. Bugging out."); - return NULL; - } - - p = malloc(sizeof *p); - - if (p == NULL) - return NULL; - - p->dub = dub; - - p->dtpc = *dtpc; - p->dupc = *dupc; - - p->dst_addr = NULL; - p->src_addr = NULL; - p->dst_cep_id = NULL; - p->src_cep_id = NULL; - p->pdu_length = NULL; - p->ttl = NULL; - p->seqno = NULL; - p->qos_id = NULL; - p->chk = NULL; - - return p; -} - -void shm_pci_destroy(shm_pci_t * pci) -{ - free(pci); -} - -int shm_pci_init(shm_pci_t * pci) -{ - if (pci == NULL) { - LOG_DBGF("Bogus input. Bugging out."); - return -EINVAL; - } - - uint8_t * pci_head = shm_du_buff_head_alloc( - pci->dub, SHM_PCI_HEAD_SIZE(pci->dtpc, pci->dupc)); - uint8_t * pci_tail = shm_du_buff_tail_alloc( - pci->dub, SHM_PCI_TAIL_SIZE(pci->dupc)); - - if (pci_head == NULL) { - LOG_DBG("Failed to allocate space for PCI at head."); - return -ENOBUFS; - } - - if (pci_tail == NULL) { - LOG_DBG("Failed to allocate space for PCI at tail."); - return -ENOBUFS; - } - - pci->dst_addr = pci_head; - pci->src_addr = (pci_head += pci->dtpc.addr_size); - pci->dst_cep_id = (pci_head += pci->dtpc.addr_size); - pci->src_cep_id = (pci_head += pci->dtpc.cep_id_size); - pci->pdu_length = (pci_head += pci->dtpc.cep_id_size); - pci->ttl = (pci_head += pci->dtpc.pdu_length_size); - pci->seqno = (pci_head += pci->dupc.ttl_size); - pci->qos_id = (pci_head += pci->dtpc.seqno_size); - - pci->chk = (pci_tail); - - return 0; -} - -void shm_pci_release(shm_pci_t * pci) -{ - if (pci == NULL) - return; - - if (pci->dub == NULL) - return; - - shm_du_buff_head_release(pci->dub, SHM_PCI_HEAD_SIZE(pci->dtpc, - pci->dupc)); - shm_du_buff_tail_release(pci->dub, SHM_PCI_TAIL_SIZE(pci->dupc)); -} diff --git a/src/ipcpd/shm_pci.h b/src/ipcpd/shm_pci.h deleted file mode 100644 index cb8dd5dd..00000000 --- a/src/ipcpd/shm_pci.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Protocol Control Information in Shared Memory Map - * - * Dimitri Staessens - * Sander Vrijders - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef OUROBOROS_IPCP_SHM_PCI_H -#define OUROBOROS_IPCP_SHM_PCI_H - -#include - -#include - -struct shm_pci; - -typedef struct shm_pci shm_pci_t; - -shm_pci_t * shm_pci_create(struct shm_du_buff * dub, - const struct ipcp_dtp_const * dtpc, - const struct ipcp_dup_const * dupc); -void shm_pci_destroy(shm_pci_t * pci); - -int shm_pci_init(shm_pci_t * pci); -void shm_pci_release(shm_pci_t * pci); - -#endif /* OUROBOROS_IPCP_SHM_PCI_H */ diff --git a/src/irmd/main.c b/src/irmd/main.c index 1f1c4839..13076cd1 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -22,6 +22,7 @@ #define OUROBOROS_PREFIX "irmd" +#include #include #include #include @@ -32,11 +33,14 @@ #include #include #include +#include #include #include +#include #include #include +#include struct ipcp_entry { struct list_head next; @@ -50,6 +54,7 @@ struct irm { }; struct irm * instance = NULL; +struct shm_du_map * dum; static pid_t find_pid_by_ipcp_name(instance_name_t * api) { @@ -59,8 +64,6 @@ static pid_t find_pid_by_ipcp_name(instance_name_t * api) struct ipcp_entry * tmp = list_entry(pos, struct ipcp_entry, next); - LOG_DBG("name is %s", api->name); - if (instance_name_cmp(api, tmp->api) == 0) return tmp->pid; } @@ -97,8 +100,9 @@ static int create_ipcp(instance_name_t * api, } tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) + if (tmp == NULL) { return -1; + } INIT_LIST_HEAD(&tmp->next); @@ -330,12 +334,45 @@ static int flow_dealloc_ipcp(uint32_t port_id) return -1; } -/* FIXME: Close sockfd on closing and release irm */ +void irmd_sig_handler(int sig, siginfo_t * info, void * c) +{ + switch(sig) { + case SIGINT: + case SIGTERM: + case SIGHUP: + shm_du_map_close(dum); + free(instance); + exit(0); + default: + return; + } +} + int main() { int sockfd; uint8_t buf[IRM_MSG_BUF_SIZE]; + struct sigaction sig_act; + + /* init sig_act */ + memset (&sig_act, 0, sizeof sig_act); + + /* install signal traps */ + sig_act.sa_sigaction = &irmd_sig_handler; + sig_act.sa_flags = SA_SIGINFO; + + sigaction(SIGINT, &sig_act, NULL); + sigaction(SIGTERM, &sig_act, NULL); + sigaction(SIGHUP, &sig_act, NULL); + + + if (access("/dev/shm/" SHM_DU_MAP_FILENAME, F_OK) != -1) + unlink("/dev/shm/" SHM_DU_MAP_FILENAME); + + if ((dum = shm_du_map_create()) == NULL) + return -1; + instance = malloc(sizeof(*instance)); if (instance == NULL) return -1; @@ -343,8 +380,10 @@ int main() INIT_LIST_HEAD(&instance->ipcps); sockfd = server_socket_open(IRM_SOCK_PATH); - if (sockfd < 0) + if (sockfd < 0) { + free(instance); return -1; + } while (true) { int cli_sockfd; diff --git a/src/lib/dif_config.proto b/src/lib/dif_config.proto index 87cb222f..05b35ea7 100644 --- a/src/lib/dif_config.proto +++ b/src/lib/dif_config.proto @@ -1,16 +1,17 @@ message dif_config_msg { - required string dif_name = 1; - required int32 ipcp_type = 2; + required string dif_name = 1; + required int32 ipcp_type = 2; // Config for normal IPCP - optional uint32 addr_size = 3; - optional uint32 cep_id_size = 4; - optional uint32 pdu_length_size = 5; - optional uint32 qos_id_size = 6; - optional uint32 seqno_size = 7; - optional uint32 ttl_size = 8; - optional uint32 chk_size = 9; - optional uint32 min_pdu_size = 10; - optional uint32 max_pdu_size = 11; + optional uint32 addr_size = 3; + optional uint32 cep_id_size = 4; + optional uint32 pdu_length_size = 5; + optional uint32 qos_id_size = 6; + optional uint32 seqno_size = 7; + optional uint32 ttl_size = 8; + optional uint32 chk_size = 9; + optional uint32 min_pdu_size = 10; + optional uint32 max_pdu_size = 11; // Config for shim UDP - optional uint32 ip_addr = 12; + optional uint32 ip_addr = 12; + optional uint32 dns_addr = 13; } \ No newline at end of file diff --git a/src/lib/flow.c b/src/lib/flow.c index 593bef1a..da0ca148 100644 --- a/src/lib/flow.c +++ b/src/lib/flow.c @@ -35,9 +35,11 @@ flow_t * flow_create(int32_t port_id) return NULL; } + INIT_LIST_HEAD(&flow->list); + flow->port_id = port_id; flow->oflags = FLOW_O_DEFAULT; - flow->state = FLOW_INIT; + flow->state = FLOW_NULL; pthread_mutex_init(&flow->lock, NULL); @@ -46,6 +48,8 @@ flow_t * flow_create(int32_t port_id) void flow_destroy(flow_t * flow) { + if (flow == NULL) + return; free(flow); } diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index a0febe4e..338d8683 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -61,7 +61,7 @@ static ipcp_msg_t * send_recv_ipcp_msg(pid_t pid, return NULL; } - buf.data = malloc(buf.size); + buf.data = malloc(IPCP_MSG_BUF_SIZE); if (buf.data == NULL) { close(sockfd); free(sock_path); @@ -103,10 +103,14 @@ pid_t ipcp_create(instance_name_t * api, enum ipcp_type ipcp_type) { pid_t pid = 0; + char irmd_pid[10]; char * api_id = NULL; size_t len = 0; - char * ipcp_dir = "bin/ipcpd"; + char * ipcp_dir = "bin"; char * full_name = NULL; + char * exec_name = NULL; + + sprintf (irmd_pid, "%u", getpid()); pid = fork(); if (pid == -1) { @@ -125,10 +129,21 @@ pid_t ipcp_create(instance_name_t * api, } sprintf(api_id, "%d", api->id); + if (ipcp_type == IPCP_NORMAL) + exec_name = IPCP_NORMAL_EXEC; + else if (ipcp_type == IPCP_SHIM_UDP) + exec_name = IPCP_SHIM_UDP_EXEC; + else { + free(api_id); + exit(EXIT_FAILURE); + } + len += strlen(INSTALL_DIR); len += strlen(ipcp_dir); - len += 2; - full_name = malloc(len); + len += strlen(exec_name); + len += 3; + + full_name = malloc(len + 1); if (full_name == NULL) { LOG_ERR("Failed to malloc"); free(api_id); @@ -138,9 +153,16 @@ pid_t ipcp_create(instance_name_t * api, strcpy(full_name, INSTALL_DIR); strcat(full_name, "/"); strcat(full_name, ipcp_dir); + strcat(full_name, "/"); + strcat(full_name, exec_name); + full_name[len] = '\0'; + + LOG_DBG("Full name is %s", full_name); char * argv[] = {full_name, - api->name, api_id, + irmd_pid, + api->name, + api_id, 0}; char * envp[] = {0}; @@ -172,22 +194,22 @@ int ipcp_destroy(pid_t pid) return 0; } -int ipcp_reg(pid_t pid, - char ** difs, - size_t difs_size) +int ipcp_reg(pid_t pid, + char ** dif_names, + size_t len) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; int ret = -1; - if (difs == NULL || - difs_size == 0 || - difs[0] == NULL) + if (dif_names == NULL || + len == 0 || + dif_names[0] == NULL) return -EINVAL; - msg.code = IPCP_MSG_CODE__IPCP_REG; - msg.dif_name = difs; - msg.n_dif_name = difs_size; + msg.code = IPCP_MSG_CODE__IPCP_REG; + msg.dif_names = dif_names; + msg.len = len; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -205,21 +227,21 @@ int ipcp_reg(pid_t pid, } int ipcp_unreg(pid_t pid, - char ** difs, - size_t difs_size) + char ** dif_names, + size_t len) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; int ret = -1; - if (difs == NULL || - difs_size == 0 || - difs[0] == NULL) + if (dif_names == NULL || + len == 0 || + dif_names[0] == NULL) return -EINVAL; - msg.code = IPCP_MSG_CODE__IPCP_UNREG; - msg.dif_name = difs; - msg.n_dif_name = difs_size; + msg.code = IPCP_MSG_CODE__IPCP_UNREG; + msg.dif_names = dif_names; + msg.len = len; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -276,36 +298,36 @@ int ipcp_enroll(pid_t pid, if (n_1_dif == NULL || member_name == NULL) return -EINVAL; - msg.code = IPCP_MSG_CODE__IPCP_ENROLL; - msg.dif_name = malloc(sizeof(*(msg.dif_name))); - if (msg.dif_name == NULL) { - LOG_ERR("Failed to malloc"); + msg.code = IPCP_MSG_CODE__IPCP_ENROLL; + msg.member_name = malloc(sizeof(*(msg.member_name))); + if (msg.member_name == NULL) { + LOG_ERR("Failed to malloc."); return -1; } - msg.dif_name[0] = n_1_dif; - msg.ap_name = member_name; + msg.n_1_dif = n_1_dif; + msg.member_name = member_name; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) { - free(msg.dif_name); + free(msg.member_name); return -1; } if (recv_msg->has_result == false) { ipcp_msg__free_unpacked(recv_msg, NULL); - free(msg.dif_name); + free(msg.member_name); return -1; } ret = recv_msg->result; ipcp_msg__free_unpacked(recv_msg, NULL); - free(msg.dif_name); + free(msg.member_name); return ret; } int ipcp_ap_reg(pid_t pid, - uint32_t reg_api_id, + uint32_t reg_ap_id, char * ap_name) { ipcp_msg_t msg = IPCP_MSG__INIT; @@ -315,10 +337,10 @@ int ipcp_ap_reg(pid_t pid, if (ap_name == NULL) return -1; - msg.code = IPCP_MSG_CODE__IPCP_AP_REG; - msg.ap_name = ap_name; - msg.has_port_id = true; - msg.port_id = reg_api_id; + msg.code = IPCP_MSG_CODE__IPCP_AP_REG; + msg.ap_name = ap_name; + msg.has_reg_ap_id = true; + msg.reg_ap_id = reg_ap_id; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -336,15 +358,15 @@ int ipcp_ap_reg(pid_t pid, } int ipcp_ap_unreg(pid_t pid, - uint32_t reg_api_id) + uint32_t reg_ap_id) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IPCP_MSG_CODE__IPCP_AP_UNREG; - msg.has_port_id = true; - msg.port_id = reg_api_id; + msg.code = IPCP_MSG_CODE__IPCP_AP_UNREG; + msg.has_reg_ap_id = true; + msg.reg_ap_id = reg_ap_id; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -375,12 +397,12 @@ int ipcp_flow_alloc(pid_t pid, if (dst_ap_name == NULL || src_ap_name == NULL || src_ae_name == NULL) return -EINVAL; - msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC; - msg.ap_name = src_ap_name; - msg.ae_name = src_ae_name; + msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC; + msg.ap_name = src_ap_name; + msg.ae_name = src_ae_name; msg.dst_ap_name = dst_ap_name; + msg.port_id = port_id; msg.has_port_id = true; - msg.port_id = port_id; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -405,11 +427,11 @@ int ipcp_flow_alloc_resp(pid_t pid, ipcp_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP; + msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP; msg.has_port_id = true; - msg.port_id = port_id; - msg.has_result = true; - msg.result = result; + msg.port_id = port_id; + msg.has_result = true; + msg.result = result; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -427,7 +449,7 @@ int ipcp_flow_alloc_resp(pid_t pid, } int ipcp_flow_req_arr(pid_t pid, - uint32_t reg_api_id, + uint32_t reg_ap_id, char * ap_name, char * ae_name) { @@ -438,13 +460,13 @@ int ipcp_flow_req_arr(pid_t pid, if (ap_name == NULL || ae_name == NULL) return -EINVAL; - msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; - msg.ap_name = ap_name; - msg.ae_name = ae_name; - msg.port_id = reg_api_id; - msg.has_port_id = true; - msg.pid = pid; - msg.has_pid = true; + msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; + msg.ap_name = ap_name; + msg.ae_name = ae_name; + msg.reg_ap_id = reg_ap_id; + msg.has_reg_ap_id = true; + msg.pid = pid; + msg.has_pid = true; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -469,11 +491,11 @@ int ipcp_flow_alloc_reply(pid_t pid, irm_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY; - msg.port_id = port_id; + msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY; + msg.port_id = port_id; msg.has_port_id = true; - msg.result = result; - msg.has_result = true; + msg.result = result; + msg.has_result = true; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto index b83c34c7..796638c7 100644 --- a/src/lib/ipcpd_messages.proto +++ b/src/lib/ipcpd_messages.proto @@ -14,12 +14,16 @@ enum ipcp_msg_code { }; message ipcp_msg { - required ipcp_msg_code code = 1; - optional string ap_name = 2; - optional dif_config_msg conf = 3; - repeated string dif_name = 4; - optional int32 result = 5; - optional uint32 port_id = 6; - optional string ae_name = 7; - optional string dst_ap_name = 8; + required ipcp_msg_code code = 1; + optional string member_name = 2; + optional string n_1_dif = 3; + repeated string dif_names = 4; + optional int32 len = 5; + optional string ap_name = 6; + optional int32 reg_ap_id = 7; + optional int32 port_id = 8; + optional string dst_ap_name = 9; + optional string ae_name = 10; + optional dif_config_msg conf = 11; + optional int32 result = 12; }; diff --git a/src/lib/irm.c b/src/lib/irm.c index 70b7b3a5..b17cb04c 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -44,6 +44,7 @@ int irm_create_ipcp(instance_name_t * api, msg.ap_name = api->name; msg.has_api_id = true; msg.api_id = api->id; + msg.has_ipcp_type = true; msg.ipcp_type = ipcp_type; recv_msg = send_recv_irm_msg(&msg); @@ -101,10 +102,10 @@ int irm_bootstrap_ipcp(instance_name_t * api, if (api == NULL || api->name == NULL || conf == NULL) return -EINVAL; - msg.code = IRM_MSG_CODE__IRM_BOOTSTRAP_IPCP; - msg.ap_name = api->name; + msg.code = IRM_MSG_CODE__IRM_BOOTSTRAP_IPCP; + msg.ap_name = api->name; msg.has_api_id = true; - msg.api_id = api->id; + msg.api_id = api->id; msg.conf = &config; config.dif_name = conf->dif_name; @@ -134,8 +135,9 @@ int irm_bootstrap_ipcp(instance_name_t * api, break; case IPCP_SHIM_UDP: config.has_ip_addr = true; - config.ip_addr = conf->ip_addr; + config.has_dns_addr = true; + config.dns_addr = conf->dns_addr; break; default: return -1; diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index 3a2432f3..92ea439e 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -24,17 +24,18 @@ enum irm_msg_code { }; message irm_msg { - required irm_msg_code code = 1; - optional string ap_name = 2; - optional uint32 api_id = 3; - optional string ae_name = 4; - optional uint32 ipcp_type = 5; - repeated string dif_name = 6; - optional int32 fd = 7; - optional int32 result = 8; - optional int32 oflags = 9; - optional string dst_ap_name = 10; - optional uint32 port_id = 11; - optional int32 pid = 12; - optional dif_config_msg conf = 13; + required irm_msg_code code = 1; + optional string ap_name = 2; + optional uint32 api_id = 3; + optional string ae_name = 4; + optional uint32 ipcp_type = 5; + repeated string dif_name = 6; + optional int32 fd = 7; + optional int32 result = 8; + optional int32 oflags = 9; + optional string dst_ap_name = 10; + optional uint32 port_id = 11; + optional uint32 reg_ap_id = 12; + optional int32 pid = 13; + optional dif_config_msg conf = 14; }; diff --git a/src/lib/sockets.c b/src/lib/sockets.c index 805dda39..4f777805 100644 --- a/src/lib/sockets.c +++ b/src/lib/sockets.c @@ -29,7 +29,6 @@ #include #include -#include #include #include @@ -61,9 +60,8 @@ int server_socket_open(char * file_name) { int sockfd; struct sockaddr_un serv_addr; - struct stat sb; - if (!stat(file_name, &sb)) { + if (access(file_name, F_OK) != -1) { /* File exists */ if (unlink(file_name)) { LOG_ERR("Failed to unlink filename: %s", @@ -113,8 +111,7 @@ irm_msg_t * send_recv_irm_msg(irm_msg_t * msg) return NULL; } - LOG_DBG("Size will be %lu", buf.size); - buf.data = malloc(buf.size); + buf.data = malloc(IRM_MSG_BUF_SIZE); if (buf.data == NULL) { close(sockfd); return NULL; diff --git a/src/lib/utils.c b/src/lib/utils.c index 77a2d44c..5744fb7c 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -28,7 +28,7 @@ int n_digits(unsigned i) int n = 1; while (i > 9) { - n++; + ++n; i /= 10; } diff --git a/src/tools/irm/irm_bootstrap_ipcp.c b/src/tools/irm/irm_bootstrap_ipcp.c index 78a09362..b90e934f 100644 --- a/src/tools/irm/irm_bootstrap_ipcp.c +++ b/src/tools/irm/irm_bootstrap_ipcp.c @@ -43,6 +43,7 @@ #define DEFAULT_CHK_SIZE 2 #define DEFAULT_MIN_PDU_SIZE 0 #define DEFAULT_MAX_PDU_SIZE 9000 +#define DEFAULT_DDNS 0 static void usage() { @@ -64,12 +65,14 @@ static void usage() " [min_pdu (default: %d)]\n" " [max_pdu (default: %d)]\n" "if TYPE == " SHIM_UDP "\n" - " ip \n", + " ip \n" + " [dns " + " (default = none: %d)]\n", DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE, DEFAULT_PDU_LEN_SIZE, DEFAULT_QOS_ID_SIZE, DEFAULT_SEQ_NO_SIZE, DEFAULT_TTL_SIZE, DEFAULT_CHK_SIZE, DEFAULT_MIN_PDU_SIZE, - DEFAULT_MAX_PDU_SIZE); + DEFAULT_MAX_PDU_SIZE, DEFAULT_DDNS); } int do_bootstrap_ipcp(int argc, char ** argv) @@ -86,6 +89,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) uint32_t min_pdu_size = DEFAULT_MIN_PDU_SIZE; uint32_t max_pdu_size = DEFAULT_MAX_PDU_SIZE; uint32_t ip_addr = 0; + uint32_t dns_addr = DEFAULT_DDNS; char * ipcp_type = NULL; char * dif_name = NULL; @@ -103,6 +107,11 @@ int do_bootstrap_ipcp(int argc, char ** argv) usage(); return -1; } + } else if (matches(*argv, "dns") == 0) { + if (inet_pton (AF_INET, *(argv + 1), &dns_addr) != 1) { + usage(); + return -1; + } } else if (matches(*argv, "addr") == 0) { addr_size = atoi(*(argv + 1)); } else if (matches(*argv, "cep_id") == 0) { @@ -156,6 +165,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) return -1; } conf.ip_addr = ip_addr; + conf.dns_addr = dns_addr; } else { usage(); return -1; -- cgit v1.2.3 From 8ebd13849c5e0db613763f3dd27220bacdb1f1e8 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 19 Apr 2016 09:34:36 +0200 Subject: ipcpd: alignment fixes in ipcp-ops.h --- src/ipcpd/ipcp-ops.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h index 69682739..2490e25c 100644 --- a/src/ipcpd/ipcp-ops.h +++ b/src/ipcpd/ipcp-ops.h @@ -39,18 +39,18 @@ struct ipcp_ops { int (* ipcp_ap_reg)(char * ap_name, uint32_t reg_ap_id); int (* ipcp_ap_unreg)(uint32_t reg_ap_id); - int (* ipcp_flow_alloc)(uint32_t port_id, - char * dst_ap_name, - char * src_ap_name, - char * src_ae_name, + int (* ipcp_flow_alloc)(uint32_t port_id, + char * dst_ap_name, + char * src_ap_name, + char * src_ae_name, struct qos_spec * qos); int (* ipcp_flow_alloc_resp)(uint32_t port_id, - int result); + int respnse); int (* ipcp_flow_dealloc)(uint32_t port_id); /* FIXME: let's see how this will work with the shm_du_map */ int (* ipcp_du_write)(uint32_t port_id, - size_t map_index); + size_t map_index); int (* ipcp_du_read)(uint32_t port_id, size_t map_index); -- cgit v1.2.3 From b2acd622d6380724fa16ee66b9f0f4463f1cd477 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 19 Apr 2016 09:42:42 +0200 Subject: ipcpd: added checks added missing NULL checks common argument check function for ipcps --- src/ipcpd/ipcp.c | 73 ++++++++++++++++++++++++++++++++++++----------- src/ipcpd/ipcp.h | 1 + src/ipcpd/shim-udp/main.c | 7 +++-- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index a1276769..0b652ff6 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -29,6 +29,23 @@ #define OUROBOROS_PREFIX "ipcpd/ipcp" #include +int ipcp_arg_check(int argc, char * argv[]) +{ + if (argc != 4) + return -1; + + /* argument 1: pid of irmd */ + if (atoi(argv[1]) == 0) + return -1; + + /* name conformity responsibility of NMS */ + + /* argument 2: ap name */ + /* argument 3: instance id */ + + return 0; +} + int ipcp_main_loop(struct ipcp * _ipcp) { int lsockfd; @@ -78,6 +95,10 @@ int ipcp_main_loop(struct ipcp * _ipcp) switch (msg->code) { case IPCP_MSG_CODE__IPCP_BOOTSTRAP: + if (_ipcp->ops->ipcp_bootstrap == NULL) { + LOG_ERR("Bootstrap unsupported."); + break; + } conf_msg = msg->conf; conf.type = conf_msg->ipcp_type; if (conf_msg->ipcp_type == IPCP_NORMAL) { @@ -102,45 +123,57 @@ int ipcp_main_loop(struct ipcp * _ipcp) break; case IPCP_MSG_CODE__IPCP_ENROLL: if (_ipcp->ops->ipcp_enroll == NULL) { - LOG_ERR("ipcp_enroll unsupported."); - } else { - ret_msg.has_result = true; - ret_msg.result = _ipcp->ops->ipcp_enroll( - msg->member_name, msg->n_1_dif); + LOG_ERR("Enroll unsupported."); + break; } + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_enroll( + msg->member_name, msg->n_1_dif); + break; case IPCP_MSG_CODE__IPCP_REG: if (_ipcp->ops->ipcp_reg == NULL) { - LOG_ERR("ipcp_reg unsupported."); + LOG_ERR("Reg unsupported."); + break; - } else { - ret_msg.has_result = true; - ret_msg.result = _ipcp->ops->ipcp_reg( - msg->dif_names, msg->len); } + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_reg( + msg->dif_names, msg->len); break; case IPCP_MSG_CODE__IPCP_UNREG: if (_ipcp->ops->ipcp_unreg == NULL) { - LOG_ERR("ipcp_unreg unsupported."); - - } else { - ret_msg.has_result = true; - ret_msg.result = _ipcp->ops->ipcp_unreg( - msg->dif_names, msg->len); + LOG_ERR("Unreg unsupported."); + break; } + ret_msg.has_result = true; + ret_msg.result = _ipcp->ops->ipcp_unreg( + msg->dif_names, msg->len); break; case IPCP_MSG_CODE__IPCP_AP_REG: + if (_ipcp->ops->ipcp_ap_reg == NULL) { + LOG_ERR("Ap_reg unsupported."); + break; + } ret_msg.has_result = true; ret_msg.result = _ipcp->ops->ipcp_ap_reg( msg->ap_name, msg->reg_ap_id); break; case IPCP_MSG_CODE__IPCP_AP_UNREG: + if (_ipcp->ops->ipcp_ap_unreg == NULL) { + LOG_ERR("Ap_unreg unsupported."); + break; + } ret_msg.has_result = true; ret_msg.result = _ipcp->ops->ipcp_ap_unreg( msg->reg_ap_id); break; case IPCP_MSG_CODE__IPCP_FLOW_ALLOC: + if (_ipcp->ops->ipcp_flow_alloc == NULL) { + LOG_ERR("Flow_alloc unsupported."); + break; + } ret_msg.has_result = true; ret_msg.result = _ipcp->ops->ipcp_flow_alloc( msg->port_id, @@ -150,11 +183,19 @@ int ipcp_main_loop(struct ipcp * _ipcp) NULL); break; case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: + if (_ipcp->ops->ipcp_flow_alloc_resp == NULL) { + LOG_ERR("Flow_alloc_resp unsupported."); + break; + } ret_msg.has_result = true; ret_msg.result = _ipcp->ops->ipcp_flow_alloc_resp( msg->port_id, msg->result); break; case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC: + if (_ipcp->ops->ipcp_flow_dealloc == NULL) { + LOG_ERR("Flow_dealloc unsupported."); + break; + } ret_msg.has_result = true; ret_msg.result = _ipcp->ops->ipcp_flow_dealloc( msg->port_id); diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index d6ddeb43..9decac8b 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -44,5 +44,6 @@ struct ipcp { }; int ipcp_main_loop(); +int ipcp_arg_check(int argc, char * argv[]); #endif diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 1fb12dc0..45620ee9 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -291,9 +291,10 @@ int main (int argc, char * argv[]) /* argument 3: instance id */ struct sigaction sig_act; - /* FIXME: clean up argument checks */ - if (argc != 4) - LOG_ERR("Wrong arguments passed."); + if (ipcp_arg_check(argc, argv)) { + LOG_ERR("Wrong arguments."); + exit(1); + } /* store the process id of the irmd */ irmd_pid = atoi(argv[1]); -- cgit v1.2.3 From 50cebfe6dbc6dd6740fc2e29b3c543d121bc1a18 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 19 Apr 2016 10:07:00 +0200 Subject: ipcpd: alignment fixes in ipcp-ops.h --- src/ipcpd/ipcp-ops.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h index 2490e25c..5c917229 100644 --- a/src/ipcpd/ipcp-ops.h +++ b/src/ipcpd/ipcp-ops.h @@ -40,12 +40,12 @@ struct ipcp_ops { uint32_t reg_ap_id); int (* ipcp_ap_unreg)(uint32_t reg_ap_id); int (* ipcp_flow_alloc)(uint32_t port_id, - char * dst_ap_name, - char * src_ap_name, - char * src_ae_name, + char * dst_ap_name, + char * src_ap_name, + char * src_ae_name, struct qos_spec * qos); int (* ipcp_flow_alloc_resp)(uint32_t port_id, - int respnse); + int response); int (* ipcp_flow_dealloc)(uint32_t port_id); /* FIXME: let's see how this will work with the shm_du_map */ -- cgit v1.2.3