summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2016-03-11 16:52:28 +0100
committerSander Vrijders <sander.vrijders@intec.ugent.be>2016-03-11 16:52:28 +0100
commitf5cf4e478bf7dec70dc22d80de706f82ef4b38f1 (patch)
tree60160c5cac28eb8cfcd376428429e03cf2e7e203
parentd68e4e5e540720d9b02e2062e3982f1c438eb1e0 (diff)
downloadouroboros-f5cf4e478bf7dec70dc22d80de706f82ef4b38f1.tar.gz
ouroboros-f5cf4e478bf7dec70dc22d80de706f82ef4b38f1.zip
lib: Add helpers for RINA names
This adds helper functions for RINA names, to aid with handling them.
-rw-r--r--include/ouroboros/CMakeLists.txt1
-rw-r--r--include/ouroboros/common.h7
-rw-r--r--include/ouroboros/da.h8
-rw-r--r--include/ouroboros/ipcp.h20
-rw-r--r--include/ouroboros/irm.h1
-rw-r--r--include/ouroboros/list.h26
-rw-r--r--include/ouroboros/rina_name.h102
-rw-r--r--include/ouroboros/sockets.h3
-rw-r--r--src/irmd/main.c164
-rw-r--r--src/lib/CMakeLists.txt1
-rw-r--r--src/lib/da.c5
-rw-r--r--src/lib/ipcp.c23
-rw-r--r--src/lib/irm.c30
-rw-r--r--src/lib/rina_name.c331
-rw-r--r--src/lib/sockets.c33
-rw-r--r--src/tools/irm/irm.c1
-rw-r--r--src/tools/irm/irm_utils.h2
17 files changed, 654 insertions, 104 deletions
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 <sander.vrijders@intec.ugent.be>
+ * Francesco Salvestrini <f.salvestrini@nextworks.it>
+ *
+ * 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 <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>
-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 <ouroboros/ipcp.h>
-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 <sander.vrijders@intec.ugent.be>
+ * Francesco Salvestrini <f.salvestrini@nextworks.it>
+ *
+ * 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);