/* Copyright 2019 by sysmocom s.f.m.c. GmbH * * All Rights Reserved * * 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, see . */ #include #include #include #include bool osmo_ipa_name_is_empty(const struct osmo_ipa_name *ipa_name) { return (!ipa_name) || (!ipa_name->len); } int osmo_ipa_name_set(struct osmo_ipa_name *ipa_name, const uint8_t *val, size_t len) { if (!val || !len) { *ipa_name = (struct osmo_ipa_name){}; return 0; } if (len > sizeof(ipa_name->val)) return -ENOSPC; ipa_name->len = len; memcpy(ipa_name->val, val, len); return 0; } static int osmo_ipa_name_set_str_va(struct osmo_ipa_name *ipa_name, const char *str_fmt, va_list ap) { if (!str_fmt) return osmo_ipa_name_set(ipa_name, NULL, 0); vsnprintf((char*)(ipa_name->val), sizeof(ipa_name->val), str_fmt, ap); ipa_name->len = strlen((char*)(ipa_name->val))+1; return 0; } int osmo_ipa_name_set_str(struct osmo_ipa_name *ipa_name, const char *str_fmt, ...) { va_list ap; int rc; va_start(ap, str_fmt); rc = osmo_ipa_name_set_str_va(ipa_name, str_fmt, ap); va_end(ap); return rc; } int osmo_ipa_name_cmp(const struct osmo_ipa_name *a, const struct osmo_ipa_name *b) { int cmp; if (a == b) return 0; if (!a) return -1; if (!b) return 1; if (!a->len && !b->len) return 0; if (!a->len && b->len) return -1; if (!b->len && a->len) return 1; if (a->len == b->len) return memcmp(a->val, b->val, a->len); else if (a->len < b->len) { cmp = memcmp(a->val, b->val, a->len); if (!cmp) cmp = -1; return cmp; } else { /* a->len > b->len */ cmp = memcmp(a->val, b->val, b->len); if (!cmp) cmp = 1; return cmp; } } /* Call osmo_ipa_name_to_str_c with OTC_SELECT. */ const char *osmo_ipa_name_to_str(const struct osmo_ipa_name *ipa_name) { return osmo_ipa_name_to_str_c(OTC_SELECT, ipa_name); } /* Return an unquoted string, not including the terminating zero. Used for writing VTY config. */ const char *osmo_ipa_name_to_str_c(void *ctx, const struct osmo_ipa_name *ipa_name) { size_t len = ipa_name->len; if (!len) return talloc_strdup(ctx, ""); if (ipa_name->val[len-1] == '\0') len--; return osmo_escape_str_c(ctx, (char*)ipa_name->val, len); } bool osmo_cni_peer_id_is_empty(const struct osmo_cni_peer_id *cni_peer_id) { if (!cni_peer_id) return true; switch (cni_peer_id->type) { case OSMO_CNI_PEER_ID_EMPTY: return true; case OSMO_CNI_PEER_ID_IPA_NAME: return osmo_ipa_name_is_empty(&cni_peer_id->ipa_name); default: return false; } } int osmo_cni_peer_id_set(struct osmo_cni_peer_id *cni_peer_id, enum osmo_cni_peer_id_type type, const uint8_t *val, size_t len) { cni_peer_id->type = type; switch (type) { case OSMO_CNI_PEER_ID_IPA_NAME: return osmo_ipa_name_set(&cni_peer_id->ipa_name, val, len); default: return -EINVAL; } } int osmo_cni_peer_id_set_str(struct osmo_cni_peer_id *cni_peer_id, enum osmo_cni_peer_id_type type, const char *str_fmt, ...) { va_list ap; int rc; *cni_peer_id = (struct osmo_cni_peer_id){}; switch (type) { case OSMO_CNI_PEER_ID_IPA_NAME: cni_peer_id->type = OSMO_CNI_PEER_ID_IPA_NAME; va_start(ap, str_fmt); rc = osmo_ipa_name_set_str_va(&cni_peer_id->ipa_name, str_fmt, ap); va_end(ap); return rc; default: return -EINVAL; } } int osmo_cni_peer_id_cmp(const struct osmo_cni_peer_id *a, const struct osmo_cni_peer_id *b) { if (a == b) return 0; if (!a) return -1; if (!b) return 1; if (a->type != b->type) return OSMO_CMP(a->type, b->type); switch (a->type) { case OSMO_CNI_PEER_ID_IPA_NAME: return osmo_ipa_name_cmp(&a->ipa_name, &b->ipa_name); default: return -EINVAL; } } const struct value_string osmo_cni_peer_id_type_names[] = { { OSMO_CNI_PEER_ID_IPA_NAME, "IPA-name" }, {} }; /* Call osmo_cni_peer_id_to_str_c with OTC_SELECT */ const char *osmo_cni_peer_id_to_str(const struct osmo_cni_peer_id *cpi) { return osmo_cni_peer_id_to_str_c(OTC_SELECT, cpi); } /* Return an unquoted string, not including the terminating zero. Used for writing VTY config. */ const char *osmo_cni_peer_id_to_str_c(void *ctx, const struct osmo_cni_peer_id *cpi) { switch (cpi->type) { case OSMO_CNI_PEER_ID_IPA_NAME: return osmo_ipa_name_to_str_c(ctx, &cpi->ipa_name); default: return talloc_strdup(ctx, osmo_cni_peer_id_type_name(cpi->type)); } }