diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/irmd/main.c | 186 | ||||
-rw-r--r-- | src/lib/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/lib/da.c | 34 | ||||
-rw-r--r-- | src/lib/ipcp.c | 64 | ||||
-rw-r--r-- | src/lib/irm.c | 32 | ||||
-rw-r--r-- | src/lib/rina_name.c | 331 | ||||
-rw-r--r-- | src/lib/sockets.c | 33 | ||||
-rw-r--r-- | src/tools/irm/irm.c | 1 | ||||
-rw-r--r-- | src/tools/irm/irm_utils.h | 2 |
9 files changed, 637 insertions, 49 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c index 262b737c..9a072382 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -26,60 +26,188 @@ #include <ouroboros/common.h> #include <ouroboros/sockets.h> #include <ouroboros/irm.h> +#include <ouroboros/ipcp.h> +#include <ouroboros/da.h> +#include <ouroboros/list.h> +#include <ouroboros/rina_name.h> + #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <errno.h> -static void create_ipcp(rina_name_t * name, +struct name_to_pid_entry { + struct list_head next; + int pid; + rina_name_t * name; +}; + +struct irm { + struct list_head name_to_pid; +}; + +static int find_pid_by_name(struct irm * instance, + rina_name_t * name) +{ + struct list_head * pos; + + list_for_each(pos, &instance->name_to_pid) { + struct name_to_pid_entry * tmp = + list_entry(pos, struct name_to_pid_entry, next); + + LOG_DBG("name is %s", name->ap_name); + + if (name_is_equal(name, tmp->name)) + return tmp->pid; + } + + return 0; +} + +static void create_ipcp(struct irm * instance, + rina_name_t name, char * ipcp_type) { - LOG_DBG("AP name is %s", name->ap_name); - LOG_DBG("AP instance id is %d", name->api_id); - LOG_DBG("AE name is %s", name->ae_name); - LOG_DBG("AE instance id is %d", name->aei_id); + int pid; + struct name_to_pid_entry * tmp; + + pid = ipcp_create(name, ipcp_type); + if (pid == 0) { + LOG_ERR("Failed to create IPCP"); + return; + } + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return; - LOG_DBG("IPCP type is %s", ipcp_type); + INIT_LIST_HEAD(&tmp->next); - LOG_MISSING; + tmp->pid = pid; + tmp->name = name_dup(&name); + if (tmp->name == NULL) { + free(tmp); + return; + } + + list_add(&tmp->next, &instance->name_to_pid); } -static void destroy_ipcp(rina_name_t * name) +static void destroy_ipcp(struct irm * instance, + rina_name_t name) { - LOG_MISSING; + int pid = 0; + struct list_head * pos; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_destroy(pid)) + LOG_ERR("Could not destroy IPCP"); + + list_for_each(pos, &instance->name_to_pid) { + struct name_to_pid_entry * tmp = + list_entry(pos, struct name_to_pid_entry, next); + + if (name_is_equal(&name, tmp->name)) + list_del(&tmp->next); + } } -static void bootstrap_ipcp(rina_name_t * name, - struct dif_config * conf) +static void bootstrap_ipcp(struct irm * instance, + rina_name_t name, + struct dif_config conf) { - LOG_MISSING; + int pid = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_bootstrap(pid, conf)) + LOG_ERR("Could not bootstrap IPCP"); } -static void enroll_ipcp(rina_name_t * name, +static void enroll_ipcp(struct irm * instance, + rina_name_t name, char * dif_name) { - LOG_MISSING; + int pid = 0; + rina_name_t * member; + char ** n_1_difs = NULL; + ssize_t n_1_difs_size = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + member = da_resolve_daf(dif_name); + if (member == NULL) { + LOG_ERR("Could not find a member of that DIF"); + return; + } + + n_1_difs_size = da_resolve_dap(member, n_1_difs); + if (n_1_difs_size != 0) + if (ipcp_enroll(pid, dif_name, *member, + n_1_difs, n_1_difs_size)) + LOG_ERR("Could not enroll IPCP"); } -static void reg_ipcp(rina_name_t * name, +static void reg_ipcp(struct irm * instance, + rina_name_t name, char ** difs, size_t difs_size) { - LOG_MISSING; + int pid = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_reg(pid, difs, difs_size)) + LOG_ERR("Could not register IPCP to N-1 DIF(s)"); } -static void unreg_ipcp(rina_name_t * name, +static void unreg_ipcp(struct irm * instance, + rina_name_t name, char ** difs, size_t difs_size) { - LOG_MISSING; + int pid = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_unreg(pid, difs, difs_size)) + LOG_ERR("Could not unregister IPCP from N-1 DIF(s)"); } +/* FIXME: Close sockfd on closing and release irm */ int main() { + struct irm * instance; int sockfd; uint8_t buf[IRM_MSG_BUF_SIZE]; + instance = malloc(sizeof(*instance)); + if (instance == NULL) + return -1; + + INIT_LIST_HEAD(&instance->name_to_pid); + sockfd = server_socket_open(IRM_SOCK_PATH); if (sockfd < 0) return -1; @@ -104,29 +232,35 @@ int main() if (msg == NULL) continue; - LOG_DBG("Got message code %d", msg->code); switch (msg->code) { case IRM_CREATE_IPCP: - create_ipcp(msg->name, msg->ipcp_type); + create_ipcp(instance, + *(msg->name), + msg->ipcp_type); break; case IRM_DESTROY_IPCP: - destroy_ipcp(msg->name); + destroy_ipcp(instance, + *(msg->name)); break; case IRM_BOOTSTRAP_IPCP: - bootstrap_ipcp(msg->name, - msg->conf); + bootstrap_ipcp(instance, + *(msg->name), + *(msg->conf)); break; case IRM_ENROLL_IPCP: - enroll_ipcp(msg->name, + enroll_ipcp(instance, + *(msg->name), msg->dif_name); break; case IRM_REG_IPCP: - reg_ipcp(msg->name, + reg_ipcp(instance, + *(msg->name), msg->difs, msg->difs_size); break; case IRM_UNREG_IPCP: - unreg_ipcp(msg->name, + unreg_ipcp(instance, + *(msg->name), msg->difs, msg->difs_size); break; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 5dad9153..c52a5609 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -8,8 +8,11 @@ set(SOURCE_FILES # Add source files here bitmap.c cdap.c + da.c du_buff.c + ipcp.c irm.c + rina_name.c sockets.c ) diff --git a/src/lib/da.c b/src/lib/da.c new file mode 100644 index 00000000..ef59a409 --- /dev/null +++ b/src/lib/da.c @@ -0,0 +1,34 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The API to instruct the DIF Allocator + * + * Sander Vrijders <[email protected]> + * + * 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 <ouroboros/da.h> + +rina_name_t * da_resolve_daf(char * daf_name) +{ + return NULL; +} + +ssize_t da_resolve_dap(rina_name_t * name, + char ** n_1_difs) +{ + return 0; +} diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c new file mode 100644 index 00000000..935330d5 --- /dev/null +++ b/src/lib/ipcp.c @@ -0,0 +1,64 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The API to instruct IPCPs + * + * Sander Vrijders <[email protected]> + * + * 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 <ouroboros/ipcp.h> + +int ipcp_create(rina_name_t name, + char * ipcp_type) +{ + /* zero means failure */ + return 0; +} + +int ipcp_destroy(int pid) +{ + return -1; +} + +int ipcp_reg(int pid, + char ** difs, + size_t difs_size) +{ + return -1; +} + +int ipcp_unreg(int pid, + char ** difs, + size_t difs_size) +{ + return -1; +} + +int ipcp_bootstrap(int pid, + struct dif_config conf) +{ + return -1; +} + +int ipcp_enroll(int pid, + char * dif_name, + rina_name_t member, + char ** n_1_difs, + ssize_t n_1_difs_size) +{ + return -1; +} diff --git a/src/lib/irm.c b/src/lib/irm.c index 519b4eb8..a1847eed 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -40,7 +40,7 @@ static int send_irm_msg(struct irm_msg * msg) buf = serialize_irm_msg(msg); if (buf == NULL) { close(sockfd); - return -1; + return -1; } if (write(sockfd, buf->data, buf->size) == -1) { @@ -63,6 +63,11 @@ int irm_create_ipcp(rina_name_t name, if (ipcp_type == NULL) return -1; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_CREATE_IPCP; msg.name = &name; msg.ipcp_type = ipcp_type; @@ -79,6 +84,11 @@ int irm_destroy_ipcp(rina_name_t name) { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_DESTROY_IPCP; msg.name = &name; @@ -95,6 +105,11 @@ int irm_bootstrap_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_BOOTSTRAP_IPCP; msg.name = &name; msg.conf = &conf; @@ -112,6 +127,11 @@ int irm_enroll_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_ENROLL_IPCP; msg.name = &name; msg.dif_name = dif_name; @@ -130,6 +150,11 @@ int irm_reg_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_REG_IPCP; msg.name = &name; msg.difs = difs; @@ -149,6 +174,11 @@ int irm_unreg_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_UNREG_IPCP; msg.name = &name; msg.difs = difs; diff --git a/src/lib/rina_name.c b/src/lib/rina_name.c new file mode 100644 index 00000000..b9044277 --- /dev/null +++ b/src/lib/rina_name.c @@ -0,0 +1,331 @@ +/* + * RINA naming related utilities + * + * Sander Vrijders <[email protected]> + * Francesco Salvestrini <[email protected]> + * + * 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. + */ + +#define OUROBOROS_PREFIX "name-utils" + +#include <ouroboros/logs.h> +#include <ouroboros/common.h> +#include <ouroboros/rina_name.h> + +#include <string.h> +#include <math.h> +#include <malloc.h> +#include <stdlib.h> + +static char * strdup(const char * src) +{ + int len = 0; + char * dst = NULL; + + if (src == NULL) + return NULL; + + len = strlen(src) + 1; + + dst = malloc(len); + if (dst == NULL) + return NULL; + + memcpy(dst, src, len); + + return dst; +} + +rina_name_t * name_create() +{ + rina_name_t * tmp; + + tmp = malloc(sizeof(rina_name_t)); + + tmp->ap_name = NULL; + tmp->api_id = 0; + tmp->ae_name = NULL; + tmp->aei_id = 0; + + return tmp; +} + +rina_name_t * name_init_from(rina_name_t * dst, + const char * ap_name, + unsigned int api_id, + const char * ae_name, + unsigned int aei_id) +{ + if (dst == NULL) + return NULL; + + /* Clean up the destination, leftovers might be there ... */ + name_fini(dst); + + dst->ap_name = strdup(ap_name); + dst->api_id = api_id; + dst->ae_name = strdup(ae_name); + dst->aei_id = aei_id; + + if (dst->ap_name == NULL || + dst->ae_name == NULL) { + name_fini(dst); + return NULL; + } + + return dst; +} + +rina_name_t * name_init_with(rina_name_t * dst, + char * ap_name, + unsigned int api_id, + char * ae_name, + unsigned int aei_id) +{ + if (dst == NULL) + return NULL; + + /* Clean up the destination, leftovers might be there ... */ + name_fini(dst); + + dst->ap_name = ap_name; + dst->api_id = api_id; + dst->ae_name = ae_name; + dst->aei_id = aei_id; + + return dst; +} + +void name_fini(rina_name_t * n) +{ + if (n == NULL) + return; + + if (n->ap_name != NULL) { + free(n->ap_name); + n->ap_name = NULL; + } + + if (n->ae_name != NULL) { + free(n->ae_name); + n->ae_name = NULL; + } +} + +void name_destroy(rina_name_t * ptr) +{ + if (ptr == NULL) + return; + + name_fini(ptr); + + free(ptr); +} + +int name_cpy(const rina_name_t * src, + rina_name_t * dst) +{ + rina_name_t * res; + + if (src == NULL || dst == NULL) + return -1; + + res = name_init_from(dst, + src->ap_name, + src->api_id, + src->ae_name, + src->aei_id); + if (res == NULL) + return -1; + + return 0; +} + +rina_name_t * name_dup(const rina_name_t * src) +{ + rina_name_t * tmp; + + if (src == NULL) + return NULL; + + tmp = name_create(); + if (tmp == NULL) + return NULL; + + if (name_cpy(src, tmp)) { + name_destroy(tmp); + return NULL; + } + + return tmp; +} + +#define NAME_CMP_FIELD(X, Y, FIELD) \ + ((X->FIELD != NULL && Y->FIELD != NULL) ? \ + strcmp(X->FIELD, Y->FIELD) : \ + ((X->FIELD == NULL && Y->FIELD == NULL) ? 0 : -1)) + +bool name_is_ok(const rina_name_t * n) +{ return (n != NULL && + n->ap_name != NULL && + strlen(n->ap_name) && + n->ae_name != NULL); } + +bool name_cmp(uint8_t flags, + const rina_name_t * a, + const rina_name_t * b) +{ + if (a == b) + return true; + + if (a == NULL || b == NULL) + return false; + + if (!(flags & NAME_CMP_ALL)) + LOG_DBG("No flags, name comparison will be meaningless ..."); + + if (flags & NAME_CMP_APN) + if (NAME_CMP_FIELD(a, b, ap_name)) + return false; + + if (flags & NAME_CMP_API) + if (a->api_id != b->api_id) + return false; + + if (flags & NAME_CMP_AEN) + if (NAME_CMP_FIELD(a, b, ae_name)) + return false; + + if (flags & NAME_CMP_AEI) + if (a->aei_id != b->aei_id) + return false; + + return true; +} + +bool name_is_equal(const rina_name_t * a, + const rina_name_t * b) +{ return name_cmp(NAME_CMP_ALL, a, b); } + +static int n_digits(unsigned i) +{ + int n = 1; + + while (i > 9) { + n++; + i /= 10; + } + + return n; +} + +#define DELIMITER "/" + +char * name_to_string(const rina_name_t * n) +{ + char * tmp; + size_t size; + const char * none = ""; + size_t none_len = strlen(none); + + if (n == NULL) + return NULL; + + size = 0; + + size += (n->ap_name != NULL ? + strlen(n->ap_name) : none_len); + size += strlen(DELIMITER); + + size += (n->api_id == 0 ? + 1 : n_digits(n->api_id)); + size += strlen(DELIMITER); + + size += (n->ae_name != NULL ? + strlen(n->ae_name) : none_len); + size += strlen(DELIMITER); + + size += (n->aei_id == 0 ? + 1 : n_digits(n->aei_id)); + size += strlen(DELIMITER); + + tmp = malloc(size); + if (!tmp) + return NULL; + + if (sprintf(tmp, "%s%s%d%s%s%s%d", + (n->ap_name != NULL ? n->ap_name : none), + DELIMITER, n->api_id, + DELIMITER, (n->ae_name != NULL ? n->ae_name : none), + DELIMITER, n->aei_id) + != size - 1) { + free(tmp); + return NULL; + } + + return tmp; +} + +rina_name_t * string_to_name(const char * s) +{ + rina_name_t * name; + + char * tmp1 = NULL; + char * tmp_ap = NULL; + char * tmp_s_api = NULL; + unsigned int tmp_api = 0; + char * tmp_ae = NULL; + char * tmp_s_aei = NULL; + unsigned int tmp_aei = 0; + char * tmp2; + + if (s == NULL) + return NULL; + + tmp1 = strdup(s); + if (tmp1 == NULL) { + return NULL; + } + + tmp_ap = strtok(tmp1, DELIMITER); + tmp_s_api = strtok(NULL, DELIMITER); + if (tmp_s_api != NULL) + tmp_api = (unsigned int) strtol(tmp_s_api, &tmp2, 10); + tmp_ae = strtok(NULL, DELIMITER); + tmp_s_aei = strtok(NULL, DELIMITER); + if (tmp_s_aei != NULL) + tmp_aei = (unsigned int) strtol(tmp_s_aei, &tmp2, 10); + + name = name_create(); + if (name == NULL) { + if (tmp1 != NULL) + free(tmp1); + return NULL; + } + + if (!name_init_from(name, tmp_ap, tmp_api, + tmp_ae, tmp_aei)) { + name_destroy(name); + if (tmp1 != NULL) + free(tmp1); + return NULL; + } + + if (tmp1 != NULL) + free(tmp1); + + return name; +} diff --git a/src/lib/sockets.c b/src/lib/sockets.c index eebd223b..90117c5c 100644 --- a/src/lib/sockets.c +++ b/src/lib/sockets.c @@ -137,7 +137,7 @@ static int deser_copy_string(uint8_t * data, } static void deser_copy_int(uint8_t * data, - int * dst, + unsigned int * dst, int * offset) { *dst = 0; @@ -185,9 +185,7 @@ buffer_t * serialize_irm_msg(struct irm_msg * msg) ser_copy_value(sizeof(enum irm_msg_code), data, &msg->code, &offset); - if (msg->name == NULL || - msg->name->ap_name == NULL || - msg->name->ae_name == NULL ) { + if (!name_is_ok(msg->name)) { LOG_ERR("Null pointer passed"); free(buf->data); free(buf); @@ -285,7 +283,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) deser_copy_enum(data->data, &msg->code, &offset); - msg->name = malloc(sizeof(*(msg->name))); + msg->name = name_create(); if (msg->name == NULL) { LOG_ERR("Failed to alloc memory"); free(msg); @@ -295,7 +293,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->name->ap_name, &offset)) { - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -305,8 +303,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->name->ae_name, &offset)) { - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -318,11 +315,9 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->ipcp_type, &offset)) { - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); - free(msg); - return NULL; + name_destroy(msg->name); + free(msg); + return NULL; } break; @@ -334,9 +329,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->dif_name, &offset)) { - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -348,9 +341,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) msg->difs = malloc(sizeof(*(msg->difs)) * difs_size); if (msg->difs == NULL) { - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -362,9 +353,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) for (j = 0; j < i; j++) free(msg->difs[j]); free(msg->difs); - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } diff --git a/src/tools/irm/irm.c b/src/tools/irm/irm.c index 0325c810..426118d1 100644 --- a/src/tools/irm/irm.c +++ b/src/tools/irm/irm.c @@ -21,6 +21,7 @@ */ #include <ouroboros/common.h> +#include <ouroboros/rina_name.h> #include <ouroboros/irm.h> #include <stdio.h> #include <string.h> diff --git a/src/tools/irm/irm_utils.h b/src/tools/irm/irm_utils.h index 9332b108..2a478d09 100644 --- a/src/tools/irm/irm_utils.h +++ b/src/tools/irm/irm_utils.h @@ -20,6 +20,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <ouroboros/rina_name.h> + #include <stdbool.h> int matches(const char * cmd, const char * pattern); |