15c62ededSKristof Provost /*- 25c62ededSKristof Provost * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 35c62ededSKristof Provost * 45c62ededSKristof Provost * Copyright (c) 2021 Rubicon Communications, LLC (Netgate) 55c62ededSKristof Provost * 65c62ededSKristof Provost * Redistribution and use in source and binary forms, with or without 75c62ededSKristof Provost * modification, are permitted provided that the following conditions 85c62ededSKristof Provost * are met: 95c62ededSKristof Provost * 1. Redistributions of source code must retain the above copyright 105c62ededSKristof Provost * notice, this list of conditions and the following disclaimer. 115c62ededSKristof Provost * 2. Redistributions in binary form must reproduce the above copyright 125c62ededSKristof Provost * notice, this list of conditions and the following disclaimer in the 135c62ededSKristof Provost * documentation and/or other materials provided with the distribution. 145c62ededSKristof Provost * 155c62ededSKristof Provost * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 165c62ededSKristof Provost * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 175c62ededSKristof Provost * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 185c62ededSKristof Provost * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 195c62ededSKristof Provost * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 205c62ededSKristof Provost * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 215c62ededSKristof Provost * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 225c62ededSKristof Provost * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 235c62ededSKristof Provost * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 245c62ededSKristof Provost * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 255c62ededSKristof Provost * SUCH DAMAGE. 265c62ededSKristof Provost * 275c62ededSKristof Provost */ 285c62ededSKristof Provost #include <sys/cdefs.h> 295c62ededSKristof Provost __FBSDID("$FreeBSD$"); 305c62ededSKristof Provost 315c62ededSKristof Provost #include <sys/param.h> 325c62ededSKristof Provost #include <sys/errno.h> 335c62ededSKristof Provost #include <sys/limits.h> 345c62ededSKristof Provost #include <sys/systm.h> 355c62ededSKristof Provost 365c62ededSKristof Provost #include <netpfil/pf/pf_nv.h> 375c62ededSKristof Provost 38eaabed8aSKristof Provost #define PF_NV_IMPL_UINT(fnname, type, max) \ 395c62ededSKristof Provost int \ 40d710367dSKristof Provost pf_nv ## fnname(const nvlist_t *nvl, const char *name, type *val) \ 415c62ededSKristof Provost { \ 425c62ededSKristof Provost uint64_t raw; \ 435c62ededSKristof Provost if (! nvlist_exists_number(nvl, name)) \ 445c62ededSKristof Provost return (EINVAL); \ 455c62ededSKristof Provost raw = nvlist_get_number(nvl, name); \ 465c62ededSKristof Provost if (raw > max) \ 475c62ededSKristof Provost return (ERANGE); \ 485c62ededSKristof Provost *val = (type)raw; \ 495c62ededSKristof Provost return (0); \ 505c62ededSKristof Provost } \ 515c62ededSKristof Provost int \ 52d710367dSKristof Provost pf_nv ## fnname ## _array(const nvlist_t *nvl, const char *name, \ 53d710367dSKristof Provost type *array, size_t maxelems, size_t *nelems) \ 545c62ededSKristof Provost { \ 555c62ededSKristof Provost const uint64_t *n; \ 565c62ededSKristof Provost size_t nitems; \ 575c62ededSKristof Provost bzero(array, sizeof(type) * maxelems); \ 585c62ededSKristof Provost if (! nvlist_exists_number_array(nvl, name)) \ 595c62ededSKristof Provost return (EINVAL); \ 605c62ededSKristof Provost n = nvlist_get_number_array(nvl, name, &nitems); \ 615c62ededSKristof Provost if (nitems != maxelems) \ 625c62ededSKristof Provost return (E2BIG); \ 635c62ededSKristof Provost if (nelems != NULL) \ 645c62ededSKristof Provost *nelems = nitems; \ 655c62ededSKristof Provost for (size_t i = 0; i < nitems; i++) { \ 665c62ededSKristof Provost if (n[i] > max) \ 675c62ededSKristof Provost return (ERANGE); \ 685c62ededSKristof Provost array[i] = (type)n[i]; \ 695c62ededSKristof Provost } \ 705c62ededSKristof Provost return (0); \ 71d710367dSKristof Provost } \ 72d710367dSKristof Provost void \ 73d710367dSKristof Provost pf_ ## fnname ## _array_nv(nvlist_t *nvl, const char *name, \ 74d710367dSKristof Provost const type *numbers, size_t count) \ 75d710367dSKristof Provost { \ 76d710367dSKristof Provost uint64_t tmp; \ 77d710367dSKristof Provost for (size_t i = 0; i < count; i++) { \ 78d710367dSKristof Provost tmp = numbers[i]; \ 79d710367dSKristof Provost nvlist_append_number_array(nvl, name, tmp); \ 80d710367dSKristof Provost } \ 815c62ededSKristof Provost } 82d710367dSKristof Provost 835c62ededSKristof Provost int 845c62ededSKristof Provost pf_nvbinary(const nvlist_t *nvl, const char *name, void *data, 855c62ededSKristof Provost size_t expected_size) 865c62ededSKristof Provost { 875c62ededSKristof Provost const uint8_t *nvdata; 885c62ededSKristof Provost size_t len; 895c62ededSKristof Provost 905c62ededSKristof Provost bzero(data, expected_size); 915c62ededSKristof Provost 925c62ededSKristof Provost if (! nvlist_exists_binary(nvl, name)) 935c62ededSKristof Provost return (EINVAL); 945c62ededSKristof Provost 955c62ededSKristof Provost nvdata = (const uint8_t *)nvlist_get_binary(nvl, name, &len); 965c62ededSKristof Provost if (len > expected_size) 975c62ededSKristof Provost return (EINVAL); 985c62ededSKristof Provost 995c62ededSKristof Provost memcpy(data, nvdata, len); 1005c62ededSKristof Provost 1015c62ededSKristof Provost return (0); 1025c62ededSKristof Provost } 1035c62ededSKristof Provost 104eaabed8aSKristof Provost PF_NV_IMPL_UINT(uint8, uint8_t, UINT8_MAX); 105eaabed8aSKristof Provost PF_NV_IMPL_UINT(uint16, uint16_t, UINT16_MAX); 106eaabed8aSKristof Provost PF_NV_IMPL_UINT(uint32, uint32_t, UINT32_MAX); 107*7606a45dSKristof Provost PF_NV_IMPL_UINT(uint64, uint64_t, UINT64_MAX); 1085c62ededSKristof Provost 1095c62ededSKristof Provost int 1105c62ededSKristof Provost pf_nvint(const nvlist_t *nvl, const char *name, int *val) 1115c62ededSKristof Provost { 1125c62ededSKristof Provost int64_t raw; 1135c62ededSKristof Provost 1145c62ededSKristof Provost if (! nvlist_exists_number(nvl, name)) 1155c62ededSKristof Provost return (EINVAL); 1165c62ededSKristof Provost 1175c62ededSKristof Provost raw = nvlist_get_number(nvl, name); 1185c62ededSKristof Provost if (raw > INT_MAX || raw < INT_MIN) 1195c62ededSKristof Provost return (ERANGE); 1205c62ededSKristof Provost 1215c62ededSKristof Provost *val = (int)raw; 1225c62ededSKristof Provost 1235c62ededSKristof Provost return (0); 1245c62ededSKristof Provost } 1255c62ededSKristof Provost 1265c62ededSKristof Provost int 1275c62ededSKristof Provost pf_nvstring(const nvlist_t *nvl, const char *name, char *str, size_t maxlen) 1285c62ededSKristof Provost { 1295c62ededSKristof Provost int ret; 1305c62ededSKristof Provost 1315c62ededSKristof Provost if (! nvlist_exists_string(nvl, name)) 1325c62ededSKristof Provost return (EINVAL); 1335c62ededSKristof Provost 1345c62ededSKristof Provost ret = strlcpy(str, nvlist_get_string(nvl, name), maxlen); 1355c62ededSKristof Provost if (ret >= maxlen) 1365c62ededSKristof Provost return (EINVAL); 1375c62ededSKristof Provost 1385c62ededSKristof Provost return (0); 1395c62ededSKristof Provost } 140