13b3a8eb9SGleb Smirnoff /* $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */ 23b3a8eb9SGleb Smirnoff 31de7b4b8SPedro F. Giffuni /*- 41de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause 51de7b4b8SPedro F. Giffuni * 63b3a8eb9SGleb Smirnoff * Copyright (c) 2002 Cedric Berger 73b3a8eb9SGleb Smirnoff * All rights reserved. 83b3a8eb9SGleb Smirnoff * 93b3a8eb9SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 103b3a8eb9SGleb Smirnoff * modification, are permitted provided that the following conditions 113b3a8eb9SGleb Smirnoff * are met: 123b3a8eb9SGleb Smirnoff * 133b3a8eb9SGleb Smirnoff * - Redistributions of source code must retain the above copyright 143b3a8eb9SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 153b3a8eb9SGleb Smirnoff * - Redistributions in binary form must reproduce the above 163b3a8eb9SGleb Smirnoff * copyright notice, this list of conditions and the following 173b3a8eb9SGleb Smirnoff * disclaimer in the documentation and/or other materials provided 183b3a8eb9SGleb Smirnoff * with the distribution. 193b3a8eb9SGleb Smirnoff * 203b3a8eb9SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 213b3a8eb9SGleb Smirnoff * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 223b3a8eb9SGleb Smirnoff * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 233b3a8eb9SGleb Smirnoff * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 243b3a8eb9SGleb Smirnoff * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 253b3a8eb9SGleb Smirnoff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 263b3a8eb9SGleb Smirnoff * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 273b3a8eb9SGleb Smirnoff * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 283b3a8eb9SGleb Smirnoff * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 293b3a8eb9SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 303b3a8eb9SGleb Smirnoff * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 313b3a8eb9SGleb Smirnoff * POSSIBILITY OF SUCH DAMAGE. 323b3a8eb9SGleb Smirnoff * 333b3a8eb9SGleb Smirnoff */ 343b3a8eb9SGleb Smirnoff 353b3a8eb9SGleb Smirnoff #include <sys/types.h> 363b3a8eb9SGleb Smirnoff #include <sys/ioctl.h> 373b3a8eb9SGleb Smirnoff #include <sys/socket.h> 383b3a8eb9SGleb Smirnoff 393b3a8eb9SGleb Smirnoff #include <net/if.h> 403b3a8eb9SGleb Smirnoff #include <net/pfvar.h> 413b3a8eb9SGleb Smirnoff 423b3a8eb9SGleb Smirnoff #include <errno.h> 433b3a8eb9SGleb Smirnoff #include <string.h> 443b3a8eb9SGleb Smirnoff #include <ctype.h> 453b3a8eb9SGleb Smirnoff #include <stdio.h> 463b3a8eb9SGleb Smirnoff #include <stdlib.h> 473b3a8eb9SGleb Smirnoff #include <limits.h> 483b3a8eb9SGleb Smirnoff #include <err.h> 493b3a8eb9SGleb Smirnoff 503b3a8eb9SGleb Smirnoff #include "pfctl.h" 513b3a8eb9SGleb Smirnoff 523b3a8eb9SGleb Smirnoff #define BUF_SIZE 256 533b3a8eb9SGleb Smirnoff 543b3a8eb9SGleb Smirnoff extern int dev; 553b3a8eb9SGleb Smirnoff 56d74024a4SJohn Baldwin static int pfr_next_token(char buf[BUF_SIZE], FILE *); 573b3a8eb9SGleb Smirnoff 583c7fbb06SKristof Provost static void 593c7fbb06SKristof Provost pfr_report_error(struct pfr_table *tbl, struct pfioc_table *io, 603c7fbb06SKristof Provost const char *err) 613c7fbb06SKristof Provost { 623c7fbb06SKristof Provost unsigned long maxcount; 633c7fbb06SKristof Provost size_t s; 643c7fbb06SKristof Provost 653c7fbb06SKristof Provost s = sizeof(maxcount); 663c7fbb06SKristof Provost if (sysctlbyname("net.pf.request_maxcount", &maxcount, &s, NULL, 673c7fbb06SKristof Provost 0) == -1) 683c7fbb06SKristof Provost return; 693c7fbb06SKristof Provost 703c7fbb06SKristof Provost if (io->pfrio_size > maxcount || io->pfrio_size2 > maxcount) 713c7fbb06SKristof Provost fprintf(stderr, "cannot %s %s: too many elements.\n" 723c7fbb06SKristof Provost "Consider increasing net.pf.request_maxcount.", 733c7fbb06SKristof Provost err, tbl->pfrt_name); 743c7fbb06SKristof Provost } 753b3a8eb9SGleb Smirnoff 763b3a8eb9SGleb Smirnoff int 773b3a8eb9SGleb Smirnoff pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags) 783b3a8eb9SGleb Smirnoff { 793b3a8eb9SGleb Smirnoff struct pfioc_table io; 803b3a8eb9SGleb Smirnoff 813b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 823b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 833b3a8eb9SGleb Smirnoff if (filter != NULL) 843b3a8eb9SGleb Smirnoff io.pfrio_table = *filter; 853b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRCLRTABLES, &io)) 863b3a8eb9SGleb Smirnoff return (-1); 873b3a8eb9SGleb Smirnoff if (ndel != NULL) 883b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 893b3a8eb9SGleb Smirnoff return (0); 903b3a8eb9SGleb Smirnoff } 913b3a8eb9SGleb Smirnoff 923b3a8eb9SGleb Smirnoff int 933b3a8eb9SGleb Smirnoff pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) 943b3a8eb9SGleb Smirnoff { 953b3a8eb9SGleb Smirnoff struct pfioc_table io; 963b3a8eb9SGleb Smirnoff 973b3a8eb9SGleb Smirnoff if (size < 0 || (size && tbl == NULL)) { 983b3a8eb9SGleb Smirnoff errno = EINVAL; 993b3a8eb9SGleb Smirnoff return (-1); 1003b3a8eb9SGleb Smirnoff } 1013b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 1023b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 1033b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 1043b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 1053b3a8eb9SGleb Smirnoff io.pfrio_size = size; 1063c7fbb06SKristof Provost if (ioctl(dev, DIOCRADDTABLES, &io)) { 1073c7fbb06SKristof Provost pfr_report_error(tbl, &io, "add table"); 1083b3a8eb9SGleb Smirnoff return (-1); 1093c7fbb06SKristof Provost } 1103b3a8eb9SGleb Smirnoff if (nadd != NULL) 1113b3a8eb9SGleb Smirnoff *nadd = io.pfrio_nadd; 1123b3a8eb9SGleb Smirnoff return (0); 1133b3a8eb9SGleb Smirnoff } 1143b3a8eb9SGleb Smirnoff 1153b3a8eb9SGleb Smirnoff int 1163b3a8eb9SGleb Smirnoff pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags) 1173b3a8eb9SGleb Smirnoff { 1183b3a8eb9SGleb Smirnoff struct pfioc_table io; 1193b3a8eb9SGleb Smirnoff 1203b3a8eb9SGleb Smirnoff if (size < 0 || (size && tbl == NULL)) { 1213b3a8eb9SGleb Smirnoff errno = EINVAL; 1223b3a8eb9SGleb Smirnoff return (-1); 1233b3a8eb9SGleb Smirnoff } 1243b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 1253b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 1263b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 1273b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 1283b3a8eb9SGleb Smirnoff io.pfrio_size = size; 1293c7fbb06SKristof Provost if (ioctl(dev, DIOCRDELTABLES, &io)) { 1303c7fbb06SKristof Provost pfr_report_error(tbl, &io, "delete table"); 1313b3a8eb9SGleb Smirnoff return (-1); 1323c7fbb06SKristof Provost } 1333b3a8eb9SGleb Smirnoff if (ndel != NULL) 1343b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 1353b3a8eb9SGleb Smirnoff return (0); 1363b3a8eb9SGleb Smirnoff } 1373b3a8eb9SGleb Smirnoff 1383b3a8eb9SGleb Smirnoff int 1393b3a8eb9SGleb Smirnoff pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size, 1403b3a8eb9SGleb Smirnoff int flags) 1413b3a8eb9SGleb Smirnoff { 1423b3a8eb9SGleb Smirnoff struct pfioc_table io; 1433b3a8eb9SGleb Smirnoff 1443b3a8eb9SGleb Smirnoff if (size == NULL || *size < 0 || (*size && tbl == NULL)) { 1453b3a8eb9SGleb Smirnoff errno = EINVAL; 1463b3a8eb9SGleb Smirnoff return (-1); 1473b3a8eb9SGleb Smirnoff } 1483b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 1493b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 1503b3a8eb9SGleb Smirnoff if (filter != NULL) 1513b3a8eb9SGleb Smirnoff io.pfrio_table = *filter; 1523b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 1533b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 1543b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 1553c7fbb06SKristof Provost if (ioctl(dev, DIOCRGETTABLES, &io)) { 1563c7fbb06SKristof Provost pfr_report_error(tbl, &io, "get table"); 1573b3a8eb9SGleb Smirnoff return (-1); 1583c7fbb06SKristof Provost } 1593b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 1603b3a8eb9SGleb Smirnoff return (0); 1613b3a8eb9SGleb Smirnoff } 1623b3a8eb9SGleb Smirnoff 1633b3a8eb9SGleb Smirnoff int 1643b3a8eb9SGleb Smirnoff pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, 1653b3a8eb9SGleb Smirnoff int flags) 1663b3a8eb9SGleb Smirnoff { 1673b3a8eb9SGleb Smirnoff struct pfioc_table io; 1683b3a8eb9SGleb Smirnoff 1693b3a8eb9SGleb Smirnoff if (size == NULL || *size < 0 || (*size && tbl == NULL)) { 1703b3a8eb9SGleb Smirnoff errno = EINVAL; 1713b3a8eb9SGleb Smirnoff return (-1); 1723b3a8eb9SGleb Smirnoff } 1733b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 1743b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 1753b3a8eb9SGleb Smirnoff if (filter != NULL) 1763b3a8eb9SGleb Smirnoff io.pfrio_table = *filter; 1773b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 1783b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 1793b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 1803c7fbb06SKristof Provost if (ioctl(dev, DIOCRGETTSTATS, &io)) { 1813c7fbb06SKristof Provost pfr_report_error(filter, &io, "get tstats for"); 1823b3a8eb9SGleb Smirnoff return (-1); 1833c7fbb06SKristof Provost } 1843b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 1853b3a8eb9SGleb Smirnoff return (0); 1863b3a8eb9SGleb Smirnoff } 1873b3a8eb9SGleb Smirnoff 1883b3a8eb9SGleb Smirnoff int 1893b3a8eb9SGleb Smirnoff pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags) 1903b3a8eb9SGleb Smirnoff { 1913b3a8eb9SGleb Smirnoff struct pfioc_table io; 1923b3a8eb9SGleb Smirnoff 1933b3a8eb9SGleb Smirnoff if (tbl == NULL) { 1943b3a8eb9SGleb Smirnoff errno = EINVAL; 1953b3a8eb9SGleb Smirnoff return (-1); 1963b3a8eb9SGleb Smirnoff } 1973b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 1983b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 1993b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 2003b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRCLRADDRS, &io)) 2013b3a8eb9SGleb Smirnoff return (-1); 2023b3a8eb9SGleb Smirnoff if (ndel != NULL) 2033b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 2043b3a8eb9SGleb Smirnoff return (0); 2053b3a8eb9SGleb Smirnoff } 2063b3a8eb9SGleb Smirnoff 2073b3a8eb9SGleb Smirnoff int 2083b3a8eb9SGleb Smirnoff pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 2093b3a8eb9SGleb Smirnoff int *nadd, int flags) 2103b3a8eb9SGleb Smirnoff { 2114823489aSReid Linnemann int ret; 2123b3a8eb9SGleb Smirnoff 2134823489aSReid Linnemann ret = pfctl_table_add_addrs(dev, tbl, addr, size, nadd, flags); 2144823489aSReid Linnemann if (ret) { 2154823489aSReid Linnemann errno = ret; 2163b3a8eb9SGleb Smirnoff return (-1); 2173b3a8eb9SGleb Smirnoff } 2183b3a8eb9SGleb Smirnoff return (0); 2193b3a8eb9SGleb Smirnoff } 2203b3a8eb9SGleb Smirnoff 2213b3a8eb9SGleb Smirnoff int 2223b3a8eb9SGleb Smirnoff pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 2233b3a8eb9SGleb Smirnoff int *ndel, int flags) 2243b3a8eb9SGleb Smirnoff { 2254823489aSReid Linnemann int ret; 2263b3a8eb9SGleb Smirnoff 2274823489aSReid Linnemann ret = pfctl_table_del_addrs(dev, tbl, addr, size, ndel, flags); 2284823489aSReid Linnemann if (ret) { 2294823489aSReid Linnemann errno = ret; 2303b3a8eb9SGleb Smirnoff return (-1); 2313b3a8eb9SGleb Smirnoff } 2323b3a8eb9SGleb Smirnoff return (0); 2333b3a8eb9SGleb Smirnoff } 2343b3a8eb9SGleb Smirnoff 2353b3a8eb9SGleb Smirnoff int 2363b3a8eb9SGleb Smirnoff pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 2373b3a8eb9SGleb Smirnoff int *size2, int *nadd, int *ndel, int *nchange, int flags) 2383b3a8eb9SGleb Smirnoff { 2394823489aSReid Linnemann int ret; 2403b3a8eb9SGleb Smirnoff 2414823489aSReid Linnemann ret = pfctl_table_set_addrs(dev, tbl, addr, size, size2, nadd, ndel, 2424823489aSReid Linnemann nchange, flags); 2434823489aSReid Linnemann if (ret) { 2444823489aSReid Linnemann errno = ret; 2453b3a8eb9SGleb Smirnoff return (-1); 2463b3a8eb9SGleb Smirnoff } 2473b3a8eb9SGleb Smirnoff return (0); 2483b3a8eb9SGleb Smirnoff } 2493b3a8eb9SGleb Smirnoff 2503b3a8eb9SGleb Smirnoff int 2513b3a8eb9SGleb Smirnoff pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size, 2523b3a8eb9SGleb Smirnoff int flags) 2533b3a8eb9SGleb Smirnoff { 2544823489aSReid Linnemann int ret; 2553b3a8eb9SGleb Smirnoff 2564823489aSReid Linnemann ret = pfctl_table_get_addrs(dev, tbl, addr, size, flags); 2574823489aSReid Linnemann if (ret) { 2584823489aSReid Linnemann errno = ret; 2593b3a8eb9SGleb Smirnoff return (-1); 2603b3a8eb9SGleb Smirnoff } 2613b3a8eb9SGleb Smirnoff return (0); 2623b3a8eb9SGleb Smirnoff } 2633b3a8eb9SGleb Smirnoff 2643b3a8eb9SGleb Smirnoff int 2653b3a8eb9SGleb Smirnoff pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, 2663b3a8eb9SGleb Smirnoff int flags) 2673b3a8eb9SGleb Smirnoff { 2683b3a8eb9SGleb Smirnoff struct pfioc_table io; 2693b3a8eb9SGleb Smirnoff 2703b3a8eb9SGleb Smirnoff if (tbl == NULL || size == NULL || *size < 0 || 2713b3a8eb9SGleb Smirnoff (*size && addr == NULL)) { 2723b3a8eb9SGleb Smirnoff errno = EINVAL; 2733b3a8eb9SGleb Smirnoff return (-1); 2743b3a8eb9SGleb Smirnoff } 2753b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 2763b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 2773b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 2783b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 2793b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 2803b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 2813c7fbb06SKristof Provost if (ioctl(dev, DIOCRGETASTATS, &io)) { 2823c7fbb06SKristof Provost pfr_report_error(tbl, &io, "get astats from"); 2833b3a8eb9SGleb Smirnoff return (-1); 2843c7fbb06SKristof Provost } 2853b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 2863b3a8eb9SGleb Smirnoff return (0); 2873b3a8eb9SGleb Smirnoff } 2883b3a8eb9SGleb Smirnoff 2893b3a8eb9SGleb Smirnoff int 2903b3a8eb9SGleb Smirnoff pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) 2913b3a8eb9SGleb Smirnoff { 2923b3a8eb9SGleb Smirnoff struct pfioc_table io; 2933b3a8eb9SGleb Smirnoff 2943b3a8eb9SGleb Smirnoff if (size < 0 || (size && !tbl)) { 2953b3a8eb9SGleb Smirnoff errno = EINVAL; 2963b3a8eb9SGleb Smirnoff return (-1); 2973b3a8eb9SGleb Smirnoff } 2983b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 2993b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 3003b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 3013b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 3023b3a8eb9SGleb Smirnoff io.pfrio_size = size; 3033c7fbb06SKristof Provost if (ioctl(dev, DIOCRCLRTSTATS, &io)) { 3043c7fbb06SKristof Provost pfr_report_error(tbl, &io, "clear tstats from"); 3053b3a8eb9SGleb Smirnoff return (-1); 3063c7fbb06SKristof Provost } 3073b3a8eb9SGleb Smirnoff if (nzero) 3083b3a8eb9SGleb Smirnoff *nzero = io.pfrio_nzero; 3093b3a8eb9SGleb Smirnoff return (0); 3103b3a8eb9SGleb Smirnoff } 3113b3a8eb9SGleb Smirnoff 3123b3a8eb9SGleb Smirnoff int 3133b3a8eb9SGleb Smirnoff pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 3143b3a8eb9SGleb Smirnoff int *nmatch, int flags) 3153b3a8eb9SGleb Smirnoff { 3163b3a8eb9SGleb Smirnoff struct pfioc_table io; 3173b3a8eb9SGleb Smirnoff 3183b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 3193b3a8eb9SGleb Smirnoff errno = EINVAL; 3203b3a8eb9SGleb Smirnoff return (-1); 3213b3a8eb9SGleb Smirnoff } 3223b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 3233b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 3243b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 3253b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 3263b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 3273b3a8eb9SGleb Smirnoff io.pfrio_size = size; 3283c7fbb06SKristof Provost if (ioctl(dev, DIOCRTSTADDRS, &io)) { 3293c7fbb06SKristof Provost pfr_report_error(tbl, &io, "test addresses in"); 3303b3a8eb9SGleb Smirnoff return (-1); 3313c7fbb06SKristof Provost } 3323b3a8eb9SGleb Smirnoff if (nmatch) 3333b3a8eb9SGleb Smirnoff *nmatch = io.pfrio_nmatch; 3343b3a8eb9SGleb Smirnoff return (0); 3353b3a8eb9SGleb Smirnoff } 3363b3a8eb9SGleb Smirnoff 3373b3a8eb9SGleb Smirnoff int 3383b3a8eb9SGleb Smirnoff pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, 3393b3a8eb9SGleb Smirnoff int *nadd, int *naddr, int ticket, int flags) 3403b3a8eb9SGleb Smirnoff { 3413b3a8eb9SGleb Smirnoff struct pfioc_table io; 3423b3a8eb9SGleb Smirnoff 3433b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 3443b3a8eb9SGleb Smirnoff errno = EINVAL; 3453b3a8eb9SGleb Smirnoff return (-1); 3463b3a8eb9SGleb Smirnoff } 3473b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 3483b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 3493b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 3503b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 3513b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 3523b3a8eb9SGleb Smirnoff io.pfrio_size = size; 3533b3a8eb9SGleb Smirnoff io.pfrio_ticket = ticket; 3543c7fbb06SKristof Provost if (ioctl(dev, DIOCRINADEFINE, &io)) { 3553c7fbb06SKristof Provost pfr_report_error(tbl, &io, "define inactive set table"); 3563b3a8eb9SGleb Smirnoff return (-1); 3573c7fbb06SKristof Provost } 3583b3a8eb9SGleb Smirnoff if (nadd != NULL) 3593b3a8eb9SGleb Smirnoff *nadd = io.pfrio_nadd; 3603b3a8eb9SGleb Smirnoff if (naddr != NULL) 3613b3a8eb9SGleb Smirnoff *naddr = io.pfrio_naddr; 3623b3a8eb9SGleb Smirnoff return (0); 3633b3a8eb9SGleb Smirnoff } 3643b3a8eb9SGleb Smirnoff 3653b3a8eb9SGleb Smirnoff /* interface management code */ 3663b3a8eb9SGleb Smirnoff 3673b3a8eb9SGleb Smirnoff int 3683b3a8eb9SGleb Smirnoff pfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size) 3693b3a8eb9SGleb Smirnoff { 3703b3a8eb9SGleb Smirnoff struct pfioc_iface io; 3713b3a8eb9SGleb Smirnoff 3723b3a8eb9SGleb Smirnoff if (size == NULL || *size < 0 || (*size && buf == NULL)) { 3733b3a8eb9SGleb Smirnoff errno = EINVAL; 3743b3a8eb9SGleb Smirnoff return (-1); 3753b3a8eb9SGleb Smirnoff } 3763b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 3773b3a8eb9SGleb Smirnoff if (filter != NULL) 3783b3a8eb9SGleb Smirnoff if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >= 3793b3a8eb9SGleb Smirnoff sizeof(io.pfiio_name)) { 3803b3a8eb9SGleb Smirnoff errno = EINVAL; 3813b3a8eb9SGleb Smirnoff return (-1); 3823b3a8eb9SGleb Smirnoff } 3833b3a8eb9SGleb Smirnoff io.pfiio_buffer = buf; 3843b3a8eb9SGleb Smirnoff io.pfiio_esize = sizeof(*buf); 3853b3a8eb9SGleb Smirnoff io.pfiio_size = *size; 3863b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCIGETIFACES, &io)) 3873b3a8eb9SGleb Smirnoff return (-1); 3883b3a8eb9SGleb Smirnoff *size = io.pfiio_size; 3893b3a8eb9SGleb Smirnoff return (0); 3903b3a8eb9SGleb Smirnoff } 3913b3a8eb9SGleb Smirnoff 3923b3a8eb9SGleb Smirnoff /* buffer management code */ 3933b3a8eb9SGleb Smirnoff 39472a3cf0fSKristof Provost const size_t buf_esize[PFRB_MAX] = { 0, 3953b3a8eb9SGleb Smirnoff sizeof(struct pfr_table), sizeof(struct pfr_tstats), 3963b3a8eb9SGleb Smirnoff sizeof(struct pfr_addr), sizeof(struct pfr_astats), 3973b3a8eb9SGleb Smirnoff sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e) 3983b3a8eb9SGleb Smirnoff }; 3993b3a8eb9SGleb Smirnoff 4003b3a8eb9SGleb Smirnoff /* 4013b3a8eb9SGleb Smirnoff * add one element to the buffer 4023b3a8eb9SGleb Smirnoff */ 4033b3a8eb9SGleb Smirnoff int 4043b3a8eb9SGleb Smirnoff pfr_buf_add(struct pfr_buffer *b, const void *e) 4053b3a8eb9SGleb Smirnoff { 4063b3a8eb9SGleb Smirnoff size_t bs; 4073b3a8eb9SGleb Smirnoff 4083b3a8eb9SGleb Smirnoff if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX || 4093b3a8eb9SGleb Smirnoff e == NULL) { 4103b3a8eb9SGleb Smirnoff errno = EINVAL; 4113b3a8eb9SGleb Smirnoff return (-1); 4123b3a8eb9SGleb Smirnoff } 4133b3a8eb9SGleb Smirnoff bs = buf_esize[b->pfrb_type]; 4143b3a8eb9SGleb Smirnoff if (b->pfrb_size == b->pfrb_msize) 4153b3a8eb9SGleb Smirnoff if (pfr_buf_grow(b, 0)) 4163b3a8eb9SGleb Smirnoff return (-1); 4173b3a8eb9SGleb Smirnoff memcpy(((caddr_t)b->pfrb_caddr) + bs * b->pfrb_size, e, bs); 4183b3a8eb9SGleb Smirnoff b->pfrb_size++; 4193b3a8eb9SGleb Smirnoff return (0); 4203b3a8eb9SGleb Smirnoff } 4213b3a8eb9SGleb Smirnoff 4223b3a8eb9SGleb Smirnoff /* 4233b3a8eb9SGleb Smirnoff * return next element of the buffer (or first one if prev is NULL) 4243b3a8eb9SGleb Smirnoff * see PFRB_FOREACH macro 4253b3a8eb9SGleb Smirnoff */ 4263b3a8eb9SGleb Smirnoff void * 4273b3a8eb9SGleb Smirnoff pfr_buf_next(struct pfr_buffer *b, const void *prev) 4283b3a8eb9SGleb Smirnoff { 4293b3a8eb9SGleb Smirnoff size_t bs; 4303b3a8eb9SGleb Smirnoff 4313b3a8eb9SGleb Smirnoff if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) 4323b3a8eb9SGleb Smirnoff return (NULL); 4333b3a8eb9SGleb Smirnoff if (b->pfrb_size == 0) 4343b3a8eb9SGleb Smirnoff return (NULL); 4353b3a8eb9SGleb Smirnoff if (prev == NULL) 4363b3a8eb9SGleb Smirnoff return (b->pfrb_caddr); 4373b3a8eb9SGleb Smirnoff bs = buf_esize[b->pfrb_type]; 4383b3a8eb9SGleb Smirnoff if ((((caddr_t)prev)-((caddr_t)b->pfrb_caddr)) / bs >= b->pfrb_size-1) 4393b3a8eb9SGleb Smirnoff return (NULL); 4403b3a8eb9SGleb Smirnoff return (((caddr_t)prev) + bs); 4413b3a8eb9SGleb Smirnoff } 4423b3a8eb9SGleb Smirnoff 4433b3a8eb9SGleb Smirnoff /* 4443b3a8eb9SGleb Smirnoff * minsize: 4453b3a8eb9SGleb Smirnoff * 0: make the buffer somewhat bigger 4463b3a8eb9SGleb Smirnoff * n: make room for "n" entries in the buffer 4473b3a8eb9SGleb Smirnoff */ 4483b3a8eb9SGleb Smirnoff int 4493b3a8eb9SGleb Smirnoff pfr_buf_grow(struct pfr_buffer *b, int minsize) 4503b3a8eb9SGleb Smirnoff { 4513b3a8eb9SGleb Smirnoff caddr_t p; 4523b3a8eb9SGleb Smirnoff size_t bs; 4533b3a8eb9SGleb Smirnoff 4543b3a8eb9SGleb Smirnoff if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) { 4553b3a8eb9SGleb Smirnoff errno = EINVAL; 4563b3a8eb9SGleb Smirnoff return (-1); 4573b3a8eb9SGleb Smirnoff } 4583b3a8eb9SGleb Smirnoff if (minsize != 0 && minsize <= b->pfrb_msize) 4593b3a8eb9SGleb Smirnoff return (0); 4603b3a8eb9SGleb Smirnoff bs = buf_esize[b->pfrb_type]; 4613b3a8eb9SGleb Smirnoff if (!b->pfrb_msize) { 4623b3a8eb9SGleb Smirnoff if (minsize < 64) 4633b3a8eb9SGleb Smirnoff minsize = 64; 4643b3a8eb9SGleb Smirnoff b->pfrb_caddr = calloc(bs, minsize); 4653b3a8eb9SGleb Smirnoff if (b->pfrb_caddr == NULL) 4663b3a8eb9SGleb Smirnoff return (-1); 4673b3a8eb9SGleb Smirnoff b->pfrb_msize = minsize; 4683b3a8eb9SGleb Smirnoff } else { 4693b3a8eb9SGleb Smirnoff if (minsize == 0) 4703b3a8eb9SGleb Smirnoff minsize = b->pfrb_msize * 2; 4713b3a8eb9SGleb Smirnoff if (minsize < 0 || minsize >= SIZE_T_MAX / bs) { 4723b3a8eb9SGleb Smirnoff /* msize overflow */ 4733b3a8eb9SGleb Smirnoff errno = ENOMEM; 4743b3a8eb9SGleb Smirnoff return (-1); 4753b3a8eb9SGleb Smirnoff } 4763b3a8eb9SGleb Smirnoff p = realloc(b->pfrb_caddr, minsize * bs); 4773b3a8eb9SGleb Smirnoff if (p == NULL) 4783b3a8eb9SGleb Smirnoff return (-1); 4793b3a8eb9SGleb Smirnoff bzero(p + b->pfrb_msize * bs, (minsize - b->pfrb_msize) * bs); 4803b3a8eb9SGleb Smirnoff b->pfrb_caddr = p; 4813b3a8eb9SGleb Smirnoff b->pfrb_msize = minsize; 4823b3a8eb9SGleb Smirnoff } 4833b3a8eb9SGleb Smirnoff return (0); 4843b3a8eb9SGleb Smirnoff } 4853b3a8eb9SGleb Smirnoff 4863b3a8eb9SGleb Smirnoff /* 4873b3a8eb9SGleb Smirnoff * reset buffer and free memory. 4883b3a8eb9SGleb Smirnoff */ 4893b3a8eb9SGleb Smirnoff void 4903b3a8eb9SGleb Smirnoff pfr_buf_clear(struct pfr_buffer *b) 4913b3a8eb9SGleb Smirnoff { 4923b3a8eb9SGleb Smirnoff if (b == NULL) 4933b3a8eb9SGleb Smirnoff return; 4943b3a8eb9SGleb Smirnoff if (b->pfrb_caddr != NULL) 4953b3a8eb9SGleb Smirnoff free(b->pfrb_caddr); 4963b3a8eb9SGleb Smirnoff b->pfrb_caddr = NULL; 4973b3a8eb9SGleb Smirnoff b->pfrb_size = b->pfrb_msize = 0; 4983b3a8eb9SGleb Smirnoff } 4993b3a8eb9SGleb Smirnoff 5003b3a8eb9SGleb Smirnoff int 5013b3a8eb9SGleb Smirnoff pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork, 5023b3a8eb9SGleb Smirnoff int (*append_addr)(struct pfr_buffer *, char *, int)) 5033b3a8eb9SGleb Smirnoff { 5043b3a8eb9SGleb Smirnoff FILE *fp; 5053b3a8eb9SGleb Smirnoff char buf[BUF_SIZE]; 5063b3a8eb9SGleb Smirnoff int rv; 5073b3a8eb9SGleb Smirnoff 5083b3a8eb9SGleb Smirnoff if (file == NULL) 5093b3a8eb9SGleb Smirnoff return (0); 5103b3a8eb9SGleb Smirnoff if (!strcmp(file, "-")) 5113b3a8eb9SGleb Smirnoff fp = stdin; 5123b3a8eb9SGleb Smirnoff else { 5133b3a8eb9SGleb Smirnoff fp = pfctl_fopen(file, "r"); 5143b3a8eb9SGleb Smirnoff if (fp == NULL) 5153b3a8eb9SGleb Smirnoff return (-1); 5163b3a8eb9SGleb Smirnoff } 5173b3a8eb9SGleb Smirnoff while ((rv = pfr_next_token(buf, fp)) == 1) 5183b3a8eb9SGleb Smirnoff if (append_addr(b, buf, nonetwork)) { 5193b3a8eb9SGleb Smirnoff rv = -1; 5203b3a8eb9SGleb Smirnoff break; 5213b3a8eb9SGleb Smirnoff } 5223b3a8eb9SGleb Smirnoff if (fp != stdin) 5233b3a8eb9SGleb Smirnoff fclose(fp); 5243b3a8eb9SGleb Smirnoff return (rv); 5253b3a8eb9SGleb Smirnoff } 5263b3a8eb9SGleb Smirnoff 5273b3a8eb9SGleb Smirnoff int 5283b3a8eb9SGleb Smirnoff pfr_next_token(char buf[BUF_SIZE], FILE *fp) 5293b3a8eb9SGleb Smirnoff { 5303b3a8eb9SGleb Smirnoff static char next_ch = ' '; 5313b3a8eb9SGleb Smirnoff int i = 0; 5323b3a8eb9SGleb Smirnoff 5333b3a8eb9SGleb Smirnoff for (;;) { 5343b3a8eb9SGleb Smirnoff /* skip spaces */ 5353b3a8eb9SGleb Smirnoff while (isspace(next_ch) && !feof(fp)) 5363b3a8eb9SGleb Smirnoff next_ch = fgetc(fp); 537*a8a95277SJuraj Lutter /* remove from '#' or ';' until end of line */ 538*a8a95277SJuraj Lutter if (next_ch == '#' || next_ch == ';') 5393b3a8eb9SGleb Smirnoff while (!feof(fp)) { 5403b3a8eb9SGleb Smirnoff next_ch = fgetc(fp); 5413b3a8eb9SGleb Smirnoff if (next_ch == '\n') 5423b3a8eb9SGleb Smirnoff break; 5433b3a8eb9SGleb Smirnoff } 5443b3a8eb9SGleb Smirnoff else 5453b3a8eb9SGleb Smirnoff break; 5463b3a8eb9SGleb Smirnoff } 5473b3a8eb9SGleb Smirnoff if (feof(fp)) { 5483b3a8eb9SGleb Smirnoff next_ch = ' '; 5493b3a8eb9SGleb Smirnoff return (0); 5503b3a8eb9SGleb Smirnoff } 5513b3a8eb9SGleb Smirnoff do { 5523b3a8eb9SGleb Smirnoff if (i < BUF_SIZE) 5533b3a8eb9SGleb Smirnoff buf[i++] = next_ch; 5543b3a8eb9SGleb Smirnoff next_ch = fgetc(fp); 5553b3a8eb9SGleb Smirnoff } while (!feof(fp) && !isspace(next_ch)); 5563b3a8eb9SGleb Smirnoff if (i >= BUF_SIZE) { 5573b3a8eb9SGleb Smirnoff errno = EINVAL; 5583b3a8eb9SGleb Smirnoff return (-1); 5593b3a8eb9SGleb Smirnoff } 5603b3a8eb9SGleb Smirnoff buf[i] = '\0'; 5613b3a8eb9SGleb Smirnoff return (1); 5623b3a8eb9SGleb Smirnoff } 5633b3a8eb9SGleb Smirnoff 5643b3a8eb9SGleb Smirnoff char * 5653b3a8eb9SGleb Smirnoff pfr_strerror(int errnum) 5663b3a8eb9SGleb Smirnoff { 5673b3a8eb9SGleb Smirnoff switch (errnum) { 5683b3a8eb9SGleb Smirnoff case ESRCH: 5693b3a8eb9SGleb Smirnoff return "Table does not exist"; 5703b3a8eb9SGleb Smirnoff case ENOENT: 5713b3a8eb9SGleb Smirnoff return "Anchor or Ruleset does not exist"; 5723b3a8eb9SGleb Smirnoff default: 5733b3a8eb9SGleb Smirnoff return strerror(errnum); 5743b3a8eb9SGleb Smirnoff } 5753b3a8eb9SGleb Smirnoff } 576