/* * (C) 2024 by sysmocom - s.f.m.c. GmbH * All Rights Reserved. * * Author: Neels Janosch Hofmeyr * * SPDX-License-Identifier: GPL-2.0+ * * 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 void range_val_set_int(struct range_val *rv, uint32_t val) { *rv = (struct range_val){ .buf = { (uint64_t)val, 0 }, .size = sizeof(val), }; } uint32_t range_val_get_int(const struct range_val *rv) { return rv->buf[0]; } void range_val_set_addr(struct range_val *rv, const struct osmo_sockaddr *val) { *rv = (struct range_val){}; rv->size = osmo_sockaddr_to_octets((void *)rv->buf, sizeof(rv->buf), val); #if !OSMO_IS_BIG_ENDIAN for (int i = 0; i < rv->size / 2; i++) { uint8_t *rvbuf = (void *)rv->buf; uint8_t tmp = rvbuf[i]; rvbuf[i] = rvbuf[rv->size - 1 - i]; rvbuf[rv->size - 1 - i] = tmp; } #endif } void range_val_get_addr(struct osmo_sockaddr *dst, const struct range_val *rv) { void *buf; #if OSMO_IS_BIG_ENDIAN buf = rv->buf; #else int i; uint8_t rev[sizeof(rv->buf)]; uint8_t *val = (void *)rv->buf; for (i = 0; i < rv->size; i++) rev[i] = val[rv->size - 1 - i]; buf = rev; #endif osmo_sockaddr_from_octets(dst, buf, rv->size); } void range_val_inc(struct range_val *rv) { uint64_t was = rv->buf[0]; rv->buf[0]++; if (rv->buf[0] < was) rv->buf[1]++; } int range_val_cmp(const struct range_val *a, const struct range_val *b) { int rc; if (a == b) return 0; if (!a) return -1; if (!b) return 1; rc = OSMO_CMP(a->buf[0], b->buf[0]); if (rc) return rc; rc = OSMO_CMP(a->buf[1], b->buf[1]); if (rc) return rc; return OSMO_CMP(a->size, b->size); } void range_next(struct range *r) { if (range_val_cmp(&r->next, &r->first) < 0) { r->next = r->first; return; } if (range_val_cmp(&r->next, &r->last) >= 0) { r->next = r->first; r->wrapped = true; return; } range_val_inc(&r->next); }