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