diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/irmd/main.c | 164 | ||||
| -rw-r--r-- | src/lib/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/lib/da.c | 5 | ||||
| -rw-r--r-- | src/lib/ipcp.c | 23 | ||||
| -rw-r--r-- | src/lib/irm.c | 30 | ||||
| -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, 528 insertions, 62 deletions
| 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); | 
