From f5cf4e478bf7dec70dc22d80de706f82ef4b38f1 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Fri, 11 Mar 2016 16:52:28 +0100 Subject: lib: Add helpers for RINA names This adds helper functions for RINA names, to aid with handling them. --- src/irmd/main.c | 164 +++++++++++++++++++---- src/lib/CMakeLists.txt | 1 + src/lib/da.c | 5 +- src/lib/ipcp.c | 23 ++-- src/lib/irm.c | 30 +++++ src/lib/rina_name.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib/sockets.c | 33 ++--- src/tools/irm/irm.c | 1 + src/tools/irm/irm_utils.h | 2 + 9 files changed, 528 insertions(+), 62 deletions(-) create mode 100644 src/lib/rina_name.c (limited to 'src') diff --git a/src/irmd/main.c b/src/irmd/main.c index f744ee7f..e28e6a28 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -28,48 +28,126 @@ #include #include #include +#include +#include #include #include #include #include -struct irm { +struct name_to_pid_entry { + struct list_head next; + int pid; + rina_name_t * name; +}; +struct irm { + struct list_head name_to_pid; }; -static void create_ipcp(rina_name_t name, +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) { - struct ipcp * instance = NULL; + int pid; + struct name_to_pid_entry * tmp; + rina_name_t * ipcp_name = NULL; - instance = ipcp_create(name, ipcp_type); - if (instance == NULL) + pid = ipcp_create(name, ipcp_type); + if (pid == 0) { LOG_ERR("Failed to create IPCP"); + return; + } + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return; + + INIT_LIST_HEAD(&tmp->next); + + tmp->pid = pid; + tmp->name = name_dup(ipcp_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) { - struct ipcp * instance = NULL; + int pid = 0; + struct list_head * pos; - if (ipcp_destroy(instance)) + 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, +static void bootstrap_ipcp(struct irm * instance, + rina_name_t name, struct dif_config conf) { - struct ipcp * instance = NULL; + int pid = 0; - if (ipcp_bootstrap(instance, conf)) + 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) { - struct ipcp * instance = NULL; + 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) { @@ -77,35 +155,60 @@ static void enroll_ipcp(rina_name_t name, return; } - if (ipcp_enroll(instance, dif_name, *member)) - LOG_ERR("Could not enroll IPCP"); + 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) { - struct ipcp * instance = NULL; + int pid = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } - if (ipcp_reg(instance, difs, difs_size)) + 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) { - struct ipcp * instance = NULL; + int pid = 0; - if (ipcp_unreg(instance, difs, difs_size)) + 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; @@ -132,26 +235,33 @@ int main() 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), + 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 349f8d73..c52a5609 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCE_FILES du_buff.c ipcp.c irm.c + rina_name.c sockets.c ) diff --git a/src/lib/da.c b/src/lib/da.c index e9888d9e..ef59a409 100644 --- a/src/lib/da.c +++ b/src/lib/da.c @@ -27,7 +27,8 @@ rina_name_t * da_resolve_daf(char * daf_name) return NULL; } -char ** da_resolve_dap(rina_name_t * name) +ssize_t da_resolve_dap(rina_name_t * name, + char ** n_1_difs) { - return NULL; + return 0; } diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index 718b5f3e..935330d5 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -22,42 +22,43 @@ #include -struct ipcp {}; - -struct ipcp * ipcp_create(rina_name_t name, - char * ipcp_type) +int ipcp_create(rina_name_t name, + char * ipcp_type) { - return NULL; + /* zero means failure */ + return 0; } -int ipcp_destroy(struct ipcp * instance) +int ipcp_destroy(int pid) { return -1; } -int ipcp_reg(struct ipcp * instance, +int ipcp_reg(int pid, char ** difs, size_t difs_size) { return -1; } -int ipcp_unreg(struct ipcp * instance, +int ipcp_unreg(int pid, char ** difs, size_t difs_size) { return -1; } -int ipcp_bootstrap(struct ipcp * instance, +int ipcp_bootstrap(int pid, struct dif_config conf) { return -1; } -int ipcp_enroll(struct ipcp * instance, +int ipcp_enroll(int pid, char * dif_name, - rina_name_t member) + 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 493cb71d..a1847eed 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -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 + * Francesco Salvestrini + * + * 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 +#include +#include + +#include +#include +#include +#include + +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 +#include #include #include #include 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 + #include int matches(const char * cmd, const char * pattern); -- cgit v1.2.3