From d68e4e5e540720d9b02e2062e3982f1c438eb1e0 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Wed, 9 Mar 2016 13:05:06 +0100 Subject: irmd, lib: Replace stubs in irmd This replaces the stubs in the irmd and calls the actual IPCP operations from the library. It also calls the DIF Allocator API in one of the operations. --- src/lib/CMakeLists.txt | 2 ++ src/lib/da.c | 33 ++++++++++++++++++++++++++ src/lib/ipcp.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/irm.c | 2 +- 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/lib/da.c create mode 100644 src/lib/ipcp.c (limited to 'src/lib') diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 5dad9153..349f8d73 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -8,7 +8,9 @@ set(SOURCE_FILES # Add source files here bitmap.c cdap.c + da.c du_buff.c + ipcp.c irm.c sockets.c ) diff --git a/src/lib/da.c b/src/lib/da.c new file mode 100644 index 00000000..e9888d9e --- /dev/null +++ b/src/lib/da.c @@ -0,0 +1,33 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The API to instruct the DIF Allocator + * + * 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 + +rina_name_t * da_resolve_daf(char * daf_name) +{ + return NULL; +} + +char ** da_resolve_dap(rina_name_t * name) +{ + return NULL; +} diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c new file mode 100644 index 00000000..718b5f3e --- /dev/null +++ b/src/lib/ipcp.c @@ -0,0 +1,63 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The API to instruct IPCPs + * + * 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 + +struct ipcp {}; + +struct ipcp * ipcp_create(rina_name_t name, + char * ipcp_type) +{ + return NULL; +} + +int ipcp_destroy(struct ipcp * instance) +{ + return -1; +} + +int ipcp_reg(struct ipcp * instance, + char ** difs, + size_t difs_size) +{ + return -1; +} + +int ipcp_unreg(struct ipcp * instance, + char ** difs, + size_t difs_size) +{ + return -1; +} + +int ipcp_bootstrap(struct ipcp * instance, + struct dif_config conf) +{ + return -1; +} + +int ipcp_enroll(struct ipcp * instance, + char * dif_name, + rina_name_t member) +{ + return -1; +} diff --git a/src/lib/irm.c b/src/lib/irm.c index 519b4eb8..493cb71d 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) { -- cgit v1.2.3 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. --- include/ouroboros/CMakeLists.txt | 1 + include/ouroboros/common.h | 7 - include/ouroboros/da.h | 8 +- include/ouroboros/ipcp.h | 20 ++- include/ouroboros/irm.h | 1 + include/ouroboros/list.h | 26 --- include/ouroboros/rina_name.h | 102 ++++++++++++ include/ouroboros/sockets.h | 3 + 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 + 17 files changed, 654 insertions(+), 104 deletions(-) create mode 100644 include/ouroboros/rina_name.h create mode 100644 src/lib/rina_name.c (limited to 'src/lib') diff --git a/include/ouroboros/CMakeLists.txt b/include/ouroboros/CMakeLists.txt index dc827fbe..e862de8c 100644 --- a/include/ouroboros/CMakeLists.txt +++ b/include/ouroboros/CMakeLists.txt @@ -9,6 +9,7 @@ set(HEADER_FILES irm.h list.h logs.h + rina_name.h sockets.h ) diff --git a/include/ouroboros/common.h b/include/ouroboros/common.h index 00d1f482..1ff4267b 100644 --- a/include/ouroboros/common.h +++ b/include/ouroboros/common.h @@ -35,13 +35,6 @@ typedef struct { size_t size; } buffer_t; -typedef struct { - char * ap_name; - int api_id; - char * ae_name; - int aei_id; -} rina_name_t; - /* FIXME: may need revision */ struct qos_spec { char * qos_name; diff --git a/include/ouroboros/da.h b/include/ouroboros/da.h index 17c25203..2a046f6b 100644 --- a/include/ouroboros/da.h +++ b/include/ouroboros/da.h @@ -24,8 +24,14 @@ #define OUROBOROS_DA_H #include "common.h" +#include "rina_name.h" rina_name_t * da_resolve_daf(char * daf_name); -char ** da_resolve_dap(rina_name_t * name); +/* + * n_1_difs is an out parameter + * The amount of n_1_difs is returned + */ +ssize_t da_resolve_dap(rina_name_t * name, + char ** n_1_difs); #endif diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index c8682ec3..39e9c909 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -24,24 +24,28 @@ #define OUROBOROS_IPCP_H #include "common.h" +#include "rina_name.h" struct ipcp; -struct ipcp * ipcp_create(rina_name_t name, - char * ipcp_type); -int ipcp_destroy(struct ipcp * instance); +/* Returns the process id */ +int ipcp_create(rina_name_t name, + char * ipcp_type); +int ipcp_destroy(int pid); -int ipcp_reg(struct ipcp * instance, +int ipcp_reg(int pid, char ** difs, size_t difs_size); -int ipcp_unreg(struct ipcp * instance, +int ipcp_unreg(int pid, char ** difs, size_t difs_size); -int ipcp_bootstrap(struct ipcp * instance, +int ipcp_bootstrap(int pid, struct dif_config conf); -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); #endif diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index 459b0e9f..a6f0d9f3 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -24,6 +24,7 @@ #define OUROBOROS_IRM_H #include "common.h" +#include "rina_name.h" int irm_create_ipcp(rina_name_t name, char * ipcp_type); diff --git a/include/ouroboros/list.h b/include/ouroboros/list.h index 1a96ddb4..f446749d 100644 --- a/include/ouroboros/list.h +++ b/include/ouroboros/list.h @@ -241,30 +241,4 @@ void list_splice_init(struct list_head * list, for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe - * against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - - #endif diff --git a/include/ouroboros/rina_name.h b/include/ouroboros/rina_name.h new file mode 100644 index 00000000..d802ae14 --- /dev/null +++ b/include/ouroboros/rina_name.h @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#ifndef RINA_NAME_H +#define RINA_NAME_H + +#include "common.h" + +typedef struct { + char * ap_name; + unsigned int api_id; + char * ae_name; + unsigned int aei_id; +} rina_name_t; + +/* + * Allocates a new name, returning the allocated object. + * In case of an error, a NULL is returned. + */ +rina_name_t * name_create(); + +/* + * Initializes a previously dynamically allocated name (i.e. name_create()) + * or a statically one (e.g. declared into a struct not as a pointer). + * Returns the passed object pointer in case everything is ok, a NULL + * otherwise. + * + * A call to name_destroy() is allowed in case of error, in order to + * release the associated resources. + * + * It is allowed to call name_init() over an already initialized object + */ +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); + +/* Takes ownership of the passed parameters */ +rina_name_t * name_init_with(rina_name_t * dst, + char * ap_name, + unsigned int api_id, + char * ae_name, + unsigned int aei_id); + +/* + * Finalize a name object, releasing all the embedded resources (without + * releasing the object itself). After name_fini() execution the passed + * object will be in the same states as at the end of name_init(). + */ +void name_fini(rina_name_t * dst); + +/* Releases all the associated resources bound to a name object */ +void name_destroy(rina_name_t * ptr); + +/* Duplicates a name object, returning the pointer to the new object */ +rina_name_t * name_dup(const rina_name_t * src); + +/* + * Copies the source object contents into the destination object, both must + * be previously allocated + */ +int name_cpy(const rina_name_t * src, rina_name_t * dst); + +bool name_is_equal(const rina_name_t * a, const rina_name_t * b); +bool name_is_ok(const rina_name_t * n); + +#define NAME_CMP_APN 0x01 +#define NAME_CMP_API 0x02 +#define NAME_CMP_AEN 0x04 +#define NAME_CMP_AEI 0x08 +#define NAME_CMP_ALL (NAME_CMP_APN | NAME_CMP_API | NAME_CMP_AEN | NAME_CMP_AEI) + +bool name_cmp(uint8_t flags, + const rina_name_t * a, + const rina_name_t * b); + +/* Returns a name as a (newly allocated) string */ +char * name_to_string(const rina_name_t * n); + +/* Inverse of name_tostring() */ +rina_name_t * string_to_name(const char * s); + +#endif diff --git a/include/ouroboros/sockets.h b/include/ouroboros/sockets.h index e2409c2b..b34537a7 100644 --- a/include/ouroboros/sockets.h +++ b/include/ouroboros/sockets.h @@ -23,6 +23,9 @@ #ifndef OUROBOROS_SOCKETS_H #define OUROBOROS_SOCKETS_H +#include "common.h" +#include "rina_name.h" + #define IRM_SOCK_PATH "/tmp/irm_sock" #define IRM_MSG_BUF_SIZE 256 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