diff options
Diffstat (limited to 'src/lib/rina_name.c')
-rw-r--r-- | src/lib/rina_name.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/src/lib/rina_name.c b/src/lib/rina_name.c new file mode 100644 index 00000000..b9044277 --- /dev/null +++ b/src/lib/rina_name.c @@ -0,0 +1,331 @@ +/* + * RINA naming related utilities + * + * Sander Vrijders <[email protected]> + * Francesco Salvestrini <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "name-utils" + +#include <ouroboros/logs.h> +#include <ouroboros/common.h> +#include <ouroboros/rina_name.h> + +#include <string.h> +#include <math.h> +#include <malloc.h> +#include <stdlib.h> + +static char * strdup(const char * src) +{ + int len = 0; + char * dst = NULL; + + if (src == NULL) + return NULL; + + len = strlen(src) + 1; + + dst = malloc(len); + if (dst == NULL) + return NULL; + + memcpy(dst, src, len); + + return dst; +} + +rina_name_t * name_create() +{ + rina_name_t * tmp; + + tmp = malloc(sizeof(rina_name_t)); + + tmp->ap_name = NULL; + tmp->api_id = 0; + tmp->ae_name = NULL; + tmp->aei_id = 0; + + return tmp; +} + +rina_name_t * name_init_from(rina_name_t * dst, + const char * ap_name, + unsigned int api_id, + const char * ae_name, + unsigned int aei_id) +{ + if (dst == NULL) + return NULL; + + /* Clean up the destination, leftovers might be there ... */ + name_fini(dst); + + dst->ap_name = strdup(ap_name); + dst->api_id = api_id; + dst->ae_name = strdup(ae_name); + dst->aei_id = aei_id; + + if (dst->ap_name == NULL || + dst->ae_name == NULL) { + name_fini(dst); + return NULL; + } + + return dst; +} + +rina_name_t * name_init_with(rina_name_t * dst, + char * ap_name, + unsigned int api_id, + char * ae_name, + unsigned int aei_id) +{ + if (dst == NULL) + return NULL; + + /* Clean up the destination, leftovers might be there ... */ + name_fini(dst); + + dst->ap_name = ap_name; + dst->api_id = api_id; + dst->ae_name = ae_name; + dst->aei_id = aei_id; + + return dst; +} + +void name_fini(rina_name_t * n) +{ + if (n == NULL) + return; + + if (n->ap_name != NULL) { + free(n->ap_name); + n->ap_name = NULL; + } + + if (n->ae_name != NULL) { + free(n->ae_name); + n->ae_name = NULL; + } +} + +void name_destroy(rina_name_t * ptr) +{ + if (ptr == NULL) + return; + + name_fini(ptr); + + free(ptr); +} + +int name_cpy(const rina_name_t * src, + rina_name_t * dst) +{ + rina_name_t * res; + + if (src == NULL || dst == NULL) + return -1; + + res = name_init_from(dst, + src->ap_name, + src->api_id, + src->ae_name, + src->aei_id); + if (res == NULL) + return -1; + + return 0; +} + +rina_name_t * name_dup(const rina_name_t * src) +{ + rina_name_t * tmp; + + if (src == NULL) + return NULL; + + tmp = name_create(); + if (tmp == NULL) + return NULL; + + if (name_cpy(src, tmp)) { + name_destroy(tmp); + return NULL; + } + + return tmp; +} + +#define NAME_CMP_FIELD(X, Y, FIELD) \ + ((X->FIELD != NULL && Y->FIELD != NULL) ? \ + strcmp(X->FIELD, Y->FIELD) : \ + ((X->FIELD == NULL && Y->FIELD == NULL) ? 0 : -1)) + +bool name_is_ok(const rina_name_t * n) +{ return (n != NULL && + n->ap_name != NULL && + strlen(n->ap_name) && + n->ae_name != NULL); } + +bool name_cmp(uint8_t flags, + const rina_name_t * a, + const rina_name_t * b) +{ + if (a == b) + return true; + + if (a == NULL || b == NULL) + return false; + + if (!(flags & NAME_CMP_ALL)) + LOG_DBG("No flags, name comparison will be meaningless ..."); + + if (flags & NAME_CMP_APN) + if (NAME_CMP_FIELD(a, b, ap_name)) + return false; + + if (flags & NAME_CMP_API) + if (a->api_id != b->api_id) + return false; + + if (flags & NAME_CMP_AEN) + if (NAME_CMP_FIELD(a, b, ae_name)) + return false; + + if (flags & NAME_CMP_AEI) + if (a->aei_id != b->aei_id) + return false; + + return true; +} + +bool name_is_equal(const rina_name_t * a, + const rina_name_t * b) +{ return name_cmp(NAME_CMP_ALL, a, b); } + +static int n_digits(unsigned i) +{ + int n = 1; + + while (i > 9) { + n++; + i /= 10; + } + + return n; +} + +#define DELIMITER "/" + +char * name_to_string(const rina_name_t * n) +{ + char * tmp; + size_t size; + const char * none = ""; + size_t none_len = strlen(none); + + if (n == NULL) + return NULL; + + size = 0; + + size += (n->ap_name != NULL ? + strlen(n->ap_name) : none_len); + size += strlen(DELIMITER); + + size += (n->api_id == 0 ? + 1 : n_digits(n->api_id)); + size += strlen(DELIMITER); + + size += (n->ae_name != NULL ? + strlen(n->ae_name) : none_len); + size += strlen(DELIMITER); + + size += (n->aei_id == 0 ? + 1 : n_digits(n->aei_id)); + size += strlen(DELIMITER); + + tmp = malloc(size); + if (!tmp) + return NULL; + + if (sprintf(tmp, "%s%s%d%s%s%s%d", + (n->ap_name != NULL ? n->ap_name : none), + DELIMITER, n->api_id, + DELIMITER, (n->ae_name != NULL ? n->ae_name : none), + DELIMITER, n->aei_id) + != size - 1) { + free(tmp); + return NULL; + } + + return tmp; +} + +rina_name_t * string_to_name(const char * s) +{ + rina_name_t * name; + + char * tmp1 = NULL; + char * tmp_ap = NULL; + char * tmp_s_api = NULL; + unsigned int tmp_api = 0; + char * tmp_ae = NULL; + char * tmp_s_aei = NULL; + unsigned int tmp_aei = 0; + char * tmp2; + + if (s == NULL) + return NULL; + + tmp1 = strdup(s); + if (tmp1 == NULL) { + return NULL; + } + + tmp_ap = strtok(tmp1, DELIMITER); + tmp_s_api = strtok(NULL, DELIMITER); + if (tmp_s_api != NULL) + tmp_api = (unsigned int) strtol(tmp_s_api, &tmp2, 10); + tmp_ae = strtok(NULL, DELIMITER); + tmp_s_aei = strtok(NULL, DELIMITER); + if (tmp_s_aei != NULL) + tmp_aei = (unsigned int) strtol(tmp_s_aei, &tmp2, 10); + + name = name_create(); + if (name == NULL) { + if (tmp1 != NULL) + free(tmp1); + return NULL; + } + + if (!name_init_from(name, tmp_ap, tmp_api, + tmp_ae, tmp_aei)) { + name_destroy(name); + if (tmp1 != NULL) + free(tmp1); + return NULL; + } + + if (tmp1 != NULL) + free(tmp1); + + return name; +} |