1*3b3a8eb9SGleb Smirnoff /* $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */ 2*3b3a8eb9SGleb Smirnoff 3*3b3a8eb9SGleb Smirnoff /* 4*3b3a8eb9SGleb Smirnoff * Copyright (c) 2002 Cedric Berger 5*3b3a8eb9SGleb Smirnoff * All rights reserved. 6*3b3a8eb9SGleb Smirnoff * 7*3b3a8eb9SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 8*3b3a8eb9SGleb Smirnoff * modification, are permitted provided that the following conditions 9*3b3a8eb9SGleb Smirnoff * are met: 10*3b3a8eb9SGleb Smirnoff * 11*3b3a8eb9SGleb Smirnoff * - Redistributions of source code must retain the above copyright 12*3b3a8eb9SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 13*3b3a8eb9SGleb Smirnoff * - Redistributions in binary form must reproduce the above 14*3b3a8eb9SGleb Smirnoff * copyright notice, this list of conditions and the following 15*3b3a8eb9SGleb Smirnoff * disclaimer in the documentation and/or other materials provided 16*3b3a8eb9SGleb Smirnoff * with the distribution. 17*3b3a8eb9SGleb Smirnoff * 18*3b3a8eb9SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19*3b3a8eb9SGleb Smirnoff * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20*3b3a8eb9SGleb Smirnoff * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21*3b3a8eb9SGleb Smirnoff * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22*3b3a8eb9SGleb Smirnoff * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23*3b3a8eb9SGleb Smirnoff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24*3b3a8eb9SGleb Smirnoff * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25*3b3a8eb9SGleb Smirnoff * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26*3b3a8eb9SGleb Smirnoff * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27*3b3a8eb9SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28*3b3a8eb9SGleb Smirnoff * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*3b3a8eb9SGleb Smirnoff * POSSIBILITY OF SUCH DAMAGE. 30*3b3a8eb9SGleb Smirnoff * 31*3b3a8eb9SGleb Smirnoff */ 32*3b3a8eb9SGleb Smirnoff 33*3b3a8eb9SGleb Smirnoff #include <sys/cdefs.h> 34*3b3a8eb9SGleb Smirnoff __FBSDID("$FreeBSD$"); 35*3b3a8eb9SGleb Smirnoff 36*3b3a8eb9SGleb Smirnoff #include <sys/types.h> 37*3b3a8eb9SGleb Smirnoff #include <sys/ioctl.h> 38*3b3a8eb9SGleb Smirnoff #include <sys/socket.h> 39*3b3a8eb9SGleb Smirnoff 40*3b3a8eb9SGleb Smirnoff #include <net/if.h> 41*3b3a8eb9SGleb Smirnoff #include <net/pfvar.h> 42*3b3a8eb9SGleb Smirnoff 43*3b3a8eb9SGleb Smirnoff #include <errno.h> 44*3b3a8eb9SGleb Smirnoff #include <string.h> 45*3b3a8eb9SGleb Smirnoff #include <ctype.h> 46*3b3a8eb9SGleb Smirnoff #include <stdio.h> 47*3b3a8eb9SGleb Smirnoff #include <stdlib.h> 48*3b3a8eb9SGleb Smirnoff #include <limits.h> 49*3b3a8eb9SGleb Smirnoff #include <err.h> 50*3b3a8eb9SGleb Smirnoff 51*3b3a8eb9SGleb Smirnoff #include "pfctl.h" 52*3b3a8eb9SGleb Smirnoff 53*3b3a8eb9SGleb Smirnoff #define BUF_SIZE 256 54*3b3a8eb9SGleb Smirnoff 55*3b3a8eb9SGleb Smirnoff extern int dev; 56*3b3a8eb9SGleb Smirnoff 57*3b3a8eb9SGleb Smirnoff static int pfr_next_token(char buf[], FILE *); 58*3b3a8eb9SGleb Smirnoff 59*3b3a8eb9SGleb Smirnoff 60*3b3a8eb9SGleb Smirnoff int 61*3b3a8eb9SGleb Smirnoff pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags) 62*3b3a8eb9SGleb Smirnoff { 63*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 64*3b3a8eb9SGleb Smirnoff 65*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 66*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 67*3b3a8eb9SGleb Smirnoff if (filter != NULL) 68*3b3a8eb9SGleb Smirnoff io.pfrio_table = *filter; 69*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRCLRTABLES, &io)) 70*3b3a8eb9SGleb Smirnoff return (-1); 71*3b3a8eb9SGleb Smirnoff if (ndel != NULL) 72*3b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 73*3b3a8eb9SGleb Smirnoff return (0); 74*3b3a8eb9SGleb Smirnoff } 75*3b3a8eb9SGleb Smirnoff 76*3b3a8eb9SGleb Smirnoff int 77*3b3a8eb9SGleb Smirnoff pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) 78*3b3a8eb9SGleb Smirnoff { 79*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 80*3b3a8eb9SGleb Smirnoff 81*3b3a8eb9SGleb Smirnoff if (size < 0 || (size && tbl == NULL)) { 82*3b3a8eb9SGleb Smirnoff errno = EINVAL; 83*3b3a8eb9SGleb Smirnoff return (-1); 84*3b3a8eb9SGleb Smirnoff } 85*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 86*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 87*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 88*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 89*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 90*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRADDTABLES, &io)) 91*3b3a8eb9SGleb Smirnoff return (-1); 92*3b3a8eb9SGleb Smirnoff if (nadd != NULL) 93*3b3a8eb9SGleb Smirnoff *nadd = io.pfrio_nadd; 94*3b3a8eb9SGleb Smirnoff return (0); 95*3b3a8eb9SGleb Smirnoff } 96*3b3a8eb9SGleb Smirnoff 97*3b3a8eb9SGleb Smirnoff int 98*3b3a8eb9SGleb Smirnoff pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags) 99*3b3a8eb9SGleb Smirnoff { 100*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 101*3b3a8eb9SGleb Smirnoff 102*3b3a8eb9SGleb Smirnoff if (size < 0 || (size && tbl == NULL)) { 103*3b3a8eb9SGleb Smirnoff errno = EINVAL; 104*3b3a8eb9SGleb Smirnoff return (-1); 105*3b3a8eb9SGleb Smirnoff } 106*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 107*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 108*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 109*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 110*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 111*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRDELTABLES, &io)) 112*3b3a8eb9SGleb Smirnoff return (-1); 113*3b3a8eb9SGleb Smirnoff if (ndel != NULL) 114*3b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 115*3b3a8eb9SGleb Smirnoff return (0); 116*3b3a8eb9SGleb Smirnoff } 117*3b3a8eb9SGleb Smirnoff 118*3b3a8eb9SGleb Smirnoff int 119*3b3a8eb9SGleb Smirnoff pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size, 120*3b3a8eb9SGleb Smirnoff int flags) 121*3b3a8eb9SGleb Smirnoff { 122*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 123*3b3a8eb9SGleb Smirnoff 124*3b3a8eb9SGleb Smirnoff if (size == NULL || *size < 0 || (*size && tbl == NULL)) { 125*3b3a8eb9SGleb Smirnoff errno = EINVAL; 126*3b3a8eb9SGleb Smirnoff return (-1); 127*3b3a8eb9SGleb Smirnoff } 128*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 129*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 130*3b3a8eb9SGleb Smirnoff if (filter != NULL) 131*3b3a8eb9SGleb Smirnoff io.pfrio_table = *filter; 132*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 133*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 134*3b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 135*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRGETTABLES, &io)) 136*3b3a8eb9SGleb Smirnoff return (-1); 137*3b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 138*3b3a8eb9SGleb Smirnoff return (0); 139*3b3a8eb9SGleb Smirnoff } 140*3b3a8eb9SGleb Smirnoff 141*3b3a8eb9SGleb Smirnoff int 142*3b3a8eb9SGleb Smirnoff pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, 143*3b3a8eb9SGleb Smirnoff int flags) 144*3b3a8eb9SGleb Smirnoff { 145*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 146*3b3a8eb9SGleb Smirnoff 147*3b3a8eb9SGleb Smirnoff if (size == NULL || *size < 0 || (*size && tbl == NULL)) { 148*3b3a8eb9SGleb Smirnoff errno = EINVAL; 149*3b3a8eb9SGleb Smirnoff return (-1); 150*3b3a8eb9SGleb Smirnoff } 151*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 152*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 153*3b3a8eb9SGleb Smirnoff if (filter != NULL) 154*3b3a8eb9SGleb Smirnoff io.pfrio_table = *filter; 155*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 156*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 157*3b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 158*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRGETTSTATS, &io)) 159*3b3a8eb9SGleb Smirnoff return (-1); 160*3b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 161*3b3a8eb9SGleb Smirnoff return (0); 162*3b3a8eb9SGleb Smirnoff } 163*3b3a8eb9SGleb Smirnoff 164*3b3a8eb9SGleb Smirnoff int 165*3b3a8eb9SGleb Smirnoff pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags) 166*3b3a8eb9SGleb Smirnoff { 167*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 168*3b3a8eb9SGleb Smirnoff 169*3b3a8eb9SGleb Smirnoff if (tbl == NULL) { 170*3b3a8eb9SGleb Smirnoff errno = EINVAL; 171*3b3a8eb9SGleb Smirnoff return (-1); 172*3b3a8eb9SGleb Smirnoff } 173*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 174*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 175*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 176*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRCLRADDRS, &io)) 177*3b3a8eb9SGleb Smirnoff return (-1); 178*3b3a8eb9SGleb Smirnoff if (ndel != NULL) 179*3b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 180*3b3a8eb9SGleb Smirnoff return (0); 181*3b3a8eb9SGleb Smirnoff } 182*3b3a8eb9SGleb Smirnoff 183*3b3a8eb9SGleb Smirnoff int 184*3b3a8eb9SGleb Smirnoff pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 185*3b3a8eb9SGleb Smirnoff int *nadd, int flags) 186*3b3a8eb9SGleb Smirnoff { 187*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 188*3b3a8eb9SGleb Smirnoff 189*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 190*3b3a8eb9SGleb Smirnoff errno = EINVAL; 191*3b3a8eb9SGleb Smirnoff return (-1); 192*3b3a8eb9SGleb Smirnoff } 193*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 194*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 195*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 196*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 197*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 198*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 199*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRADDADDRS, &io)) 200*3b3a8eb9SGleb Smirnoff return (-1); 201*3b3a8eb9SGleb Smirnoff if (nadd != NULL) 202*3b3a8eb9SGleb Smirnoff *nadd = io.pfrio_nadd; 203*3b3a8eb9SGleb Smirnoff return (0); 204*3b3a8eb9SGleb Smirnoff } 205*3b3a8eb9SGleb Smirnoff 206*3b3a8eb9SGleb Smirnoff int 207*3b3a8eb9SGleb Smirnoff pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 208*3b3a8eb9SGleb Smirnoff int *ndel, int flags) 209*3b3a8eb9SGleb Smirnoff { 210*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 211*3b3a8eb9SGleb Smirnoff 212*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 213*3b3a8eb9SGleb Smirnoff errno = EINVAL; 214*3b3a8eb9SGleb Smirnoff return (-1); 215*3b3a8eb9SGleb Smirnoff } 216*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 217*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 218*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 219*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 220*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 221*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 222*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRDELADDRS, &io)) 223*3b3a8eb9SGleb Smirnoff return (-1); 224*3b3a8eb9SGleb Smirnoff if (ndel != NULL) 225*3b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 226*3b3a8eb9SGleb Smirnoff return (0); 227*3b3a8eb9SGleb Smirnoff } 228*3b3a8eb9SGleb Smirnoff 229*3b3a8eb9SGleb Smirnoff int 230*3b3a8eb9SGleb Smirnoff pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 231*3b3a8eb9SGleb Smirnoff int *size2, int *nadd, int *ndel, int *nchange, int flags) 232*3b3a8eb9SGleb Smirnoff { 233*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 234*3b3a8eb9SGleb Smirnoff 235*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 236*3b3a8eb9SGleb Smirnoff errno = EINVAL; 237*3b3a8eb9SGleb Smirnoff return (-1); 238*3b3a8eb9SGleb Smirnoff } 239*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 240*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 241*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 242*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 243*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 244*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 245*3b3a8eb9SGleb Smirnoff io.pfrio_size2 = (size2 != NULL) ? *size2 : 0; 246*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRSETADDRS, &io)) 247*3b3a8eb9SGleb Smirnoff return (-1); 248*3b3a8eb9SGleb Smirnoff if (nadd != NULL) 249*3b3a8eb9SGleb Smirnoff *nadd = io.pfrio_nadd; 250*3b3a8eb9SGleb Smirnoff if (ndel != NULL) 251*3b3a8eb9SGleb Smirnoff *ndel = io.pfrio_ndel; 252*3b3a8eb9SGleb Smirnoff if (nchange != NULL) 253*3b3a8eb9SGleb Smirnoff *nchange = io.pfrio_nchange; 254*3b3a8eb9SGleb Smirnoff if (size2 != NULL) 255*3b3a8eb9SGleb Smirnoff *size2 = io.pfrio_size2; 256*3b3a8eb9SGleb Smirnoff return (0); 257*3b3a8eb9SGleb Smirnoff } 258*3b3a8eb9SGleb Smirnoff 259*3b3a8eb9SGleb Smirnoff int 260*3b3a8eb9SGleb Smirnoff pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size, 261*3b3a8eb9SGleb Smirnoff int flags) 262*3b3a8eb9SGleb Smirnoff { 263*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 264*3b3a8eb9SGleb Smirnoff 265*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size == NULL || *size < 0 || 266*3b3a8eb9SGleb Smirnoff (*size && addr == NULL)) { 267*3b3a8eb9SGleb Smirnoff errno = EINVAL; 268*3b3a8eb9SGleb Smirnoff return (-1); 269*3b3a8eb9SGleb Smirnoff } 270*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 271*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 272*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 273*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 274*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 275*3b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 276*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRGETADDRS, &io)) 277*3b3a8eb9SGleb Smirnoff return (-1); 278*3b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 279*3b3a8eb9SGleb Smirnoff return (0); 280*3b3a8eb9SGleb Smirnoff } 281*3b3a8eb9SGleb Smirnoff 282*3b3a8eb9SGleb Smirnoff int 283*3b3a8eb9SGleb Smirnoff pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, 284*3b3a8eb9SGleb Smirnoff int flags) 285*3b3a8eb9SGleb Smirnoff { 286*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 287*3b3a8eb9SGleb Smirnoff 288*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size == NULL || *size < 0 || 289*3b3a8eb9SGleb Smirnoff (*size && addr == NULL)) { 290*3b3a8eb9SGleb Smirnoff errno = EINVAL; 291*3b3a8eb9SGleb Smirnoff return (-1); 292*3b3a8eb9SGleb Smirnoff } 293*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 294*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 295*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 296*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 297*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 298*3b3a8eb9SGleb Smirnoff io.pfrio_size = *size; 299*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRGETASTATS, &io)) 300*3b3a8eb9SGleb Smirnoff return (-1); 301*3b3a8eb9SGleb Smirnoff *size = io.pfrio_size; 302*3b3a8eb9SGleb Smirnoff return (0); 303*3b3a8eb9SGleb Smirnoff } 304*3b3a8eb9SGleb Smirnoff 305*3b3a8eb9SGleb Smirnoff int 306*3b3a8eb9SGleb Smirnoff pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) 307*3b3a8eb9SGleb Smirnoff { 308*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 309*3b3a8eb9SGleb Smirnoff 310*3b3a8eb9SGleb Smirnoff if (size < 0 || (size && !tbl)) { 311*3b3a8eb9SGleb Smirnoff errno = EINVAL; 312*3b3a8eb9SGleb Smirnoff return (-1); 313*3b3a8eb9SGleb Smirnoff } 314*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 315*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 316*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = tbl; 317*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*tbl); 318*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 319*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRCLRTSTATS, &io)) 320*3b3a8eb9SGleb Smirnoff return (-1); 321*3b3a8eb9SGleb Smirnoff if (nzero) 322*3b3a8eb9SGleb Smirnoff *nzero = io.pfrio_nzero; 323*3b3a8eb9SGleb Smirnoff return (0); 324*3b3a8eb9SGleb Smirnoff } 325*3b3a8eb9SGleb Smirnoff 326*3b3a8eb9SGleb Smirnoff int 327*3b3a8eb9SGleb Smirnoff pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 328*3b3a8eb9SGleb Smirnoff int *nmatch, int flags) 329*3b3a8eb9SGleb Smirnoff { 330*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 331*3b3a8eb9SGleb Smirnoff 332*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 333*3b3a8eb9SGleb Smirnoff errno = EINVAL; 334*3b3a8eb9SGleb Smirnoff return (-1); 335*3b3a8eb9SGleb Smirnoff } 336*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 337*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 338*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 339*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 340*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 341*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 342*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRTSTADDRS, &io)) 343*3b3a8eb9SGleb Smirnoff return (-1); 344*3b3a8eb9SGleb Smirnoff if (nmatch) 345*3b3a8eb9SGleb Smirnoff *nmatch = io.pfrio_nmatch; 346*3b3a8eb9SGleb Smirnoff return (0); 347*3b3a8eb9SGleb Smirnoff } 348*3b3a8eb9SGleb Smirnoff 349*3b3a8eb9SGleb Smirnoff int 350*3b3a8eb9SGleb Smirnoff pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, 351*3b3a8eb9SGleb Smirnoff int *nadd, int *naddr, int ticket, int flags) 352*3b3a8eb9SGleb Smirnoff { 353*3b3a8eb9SGleb Smirnoff struct pfioc_table io; 354*3b3a8eb9SGleb Smirnoff 355*3b3a8eb9SGleb Smirnoff if (tbl == NULL || size < 0 || (size && addr == NULL)) { 356*3b3a8eb9SGleb Smirnoff errno = EINVAL; 357*3b3a8eb9SGleb Smirnoff return (-1); 358*3b3a8eb9SGleb Smirnoff } 359*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 360*3b3a8eb9SGleb Smirnoff io.pfrio_flags = flags; 361*3b3a8eb9SGleb Smirnoff io.pfrio_table = *tbl; 362*3b3a8eb9SGleb Smirnoff io.pfrio_buffer = addr; 363*3b3a8eb9SGleb Smirnoff io.pfrio_esize = sizeof(*addr); 364*3b3a8eb9SGleb Smirnoff io.pfrio_size = size; 365*3b3a8eb9SGleb Smirnoff io.pfrio_ticket = ticket; 366*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCRINADEFINE, &io)) 367*3b3a8eb9SGleb Smirnoff return (-1); 368*3b3a8eb9SGleb Smirnoff if (nadd != NULL) 369*3b3a8eb9SGleb Smirnoff *nadd = io.pfrio_nadd; 370*3b3a8eb9SGleb Smirnoff if (naddr != NULL) 371*3b3a8eb9SGleb Smirnoff *naddr = io.pfrio_naddr; 372*3b3a8eb9SGleb Smirnoff return (0); 373*3b3a8eb9SGleb Smirnoff } 374*3b3a8eb9SGleb Smirnoff 375*3b3a8eb9SGleb Smirnoff /* interface management code */ 376*3b3a8eb9SGleb Smirnoff 377*3b3a8eb9SGleb Smirnoff int 378*3b3a8eb9SGleb Smirnoff pfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size) 379*3b3a8eb9SGleb Smirnoff { 380*3b3a8eb9SGleb Smirnoff struct pfioc_iface io; 381*3b3a8eb9SGleb Smirnoff 382*3b3a8eb9SGleb Smirnoff if (size == NULL || *size < 0 || (*size && buf == NULL)) { 383*3b3a8eb9SGleb Smirnoff errno = EINVAL; 384*3b3a8eb9SGleb Smirnoff return (-1); 385*3b3a8eb9SGleb Smirnoff } 386*3b3a8eb9SGleb Smirnoff bzero(&io, sizeof io); 387*3b3a8eb9SGleb Smirnoff if (filter != NULL) 388*3b3a8eb9SGleb Smirnoff if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >= 389*3b3a8eb9SGleb Smirnoff sizeof(io.pfiio_name)) { 390*3b3a8eb9SGleb Smirnoff errno = EINVAL; 391*3b3a8eb9SGleb Smirnoff return (-1); 392*3b3a8eb9SGleb Smirnoff } 393*3b3a8eb9SGleb Smirnoff io.pfiio_buffer = buf; 394*3b3a8eb9SGleb Smirnoff io.pfiio_esize = sizeof(*buf); 395*3b3a8eb9SGleb Smirnoff io.pfiio_size = *size; 396*3b3a8eb9SGleb Smirnoff if (ioctl(dev, DIOCIGETIFACES, &io)) 397*3b3a8eb9SGleb Smirnoff return (-1); 398*3b3a8eb9SGleb Smirnoff *size = io.pfiio_size; 399*3b3a8eb9SGleb Smirnoff return (0); 400*3b3a8eb9SGleb Smirnoff } 401*3b3a8eb9SGleb Smirnoff 402*3b3a8eb9SGleb Smirnoff /* buffer management code */ 403*3b3a8eb9SGleb Smirnoff 404*3b3a8eb9SGleb Smirnoff size_t buf_esize[PFRB_MAX] = { 0, 405*3b3a8eb9SGleb Smirnoff sizeof(struct pfr_table), sizeof(struct pfr_tstats), 406*3b3a8eb9SGleb Smirnoff sizeof(struct pfr_addr), sizeof(struct pfr_astats), 407*3b3a8eb9SGleb Smirnoff sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e) 408*3b3a8eb9SGleb Smirnoff }; 409*3b3a8eb9SGleb Smirnoff 410*3b3a8eb9SGleb Smirnoff /* 411*3b3a8eb9SGleb Smirnoff * add one element to the buffer 412*3b3a8eb9SGleb Smirnoff */ 413*3b3a8eb9SGleb Smirnoff int 414*3b3a8eb9SGleb Smirnoff pfr_buf_add(struct pfr_buffer *b, const void *e) 415*3b3a8eb9SGleb Smirnoff { 416*3b3a8eb9SGleb Smirnoff size_t bs; 417*3b3a8eb9SGleb Smirnoff 418*3b3a8eb9SGleb Smirnoff if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX || 419*3b3a8eb9SGleb Smirnoff e == NULL) { 420*3b3a8eb9SGleb Smirnoff errno = EINVAL; 421*3b3a8eb9SGleb Smirnoff return (-1); 422*3b3a8eb9SGleb Smirnoff } 423*3b3a8eb9SGleb Smirnoff bs = buf_esize[b->pfrb_type]; 424*3b3a8eb9SGleb Smirnoff if (b->pfrb_size == b->pfrb_msize) 425*3b3a8eb9SGleb Smirnoff if (pfr_buf_grow(b, 0)) 426*3b3a8eb9SGleb Smirnoff return (-1); 427*3b3a8eb9SGleb Smirnoff memcpy(((caddr_t)b->pfrb_caddr) + bs * b->pfrb_size, e, bs); 428*3b3a8eb9SGleb Smirnoff b->pfrb_size++; 429*3b3a8eb9SGleb Smirnoff return (0); 430*3b3a8eb9SGleb Smirnoff } 431*3b3a8eb9SGleb Smirnoff 432*3b3a8eb9SGleb Smirnoff /* 433*3b3a8eb9SGleb Smirnoff * return next element of the buffer (or first one if prev is NULL) 434*3b3a8eb9SGleb Smirnoff * see PFRB_FOREACH macro 435*3b3a8eb9SGleb Smirnoff */ 436*3b3a8eb9SGleb Smirnoff void * 437*3b3a8eb9SGleb Smirnoff pfr_buf_next(struct pfr_buffer *b, const void *prev) 438*3b3a8eb9SGleb Smirnoff { 439*3b3a8eb9SGleb Smirnoff size_t bs; 440*3b3a8eb9SGleb Smirnoff 441*3b3a8eb9SGleb Smirnoff if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) 442*3b3a8eb9SGleb Smirnoff return (NULL); 443*3b3a8eb9SGleb Smirnoff if (b->pfrb_size == 0) 444*3b3a8eb9SGleb Smirnoff return (NULL); 445*3b3a8eb9SGleb Smirnoff if (prev == NULL) 446*3b3a8eb9SGleb Smirnoff return (b->pfrb_caddr); 447*3b3a8eb9SGleb Smirnoff bs = buf_esize[b->pfrb_type]; 448*3b3a8eb9SGleb Smirnoff if ((((caddr_t)prev)-((caddr_t)b->pfrb_caddr)) / bs >= b->pfrb_size-1) 449*3b3a8eb9SGleb Smirnoff return (NULL); 450*3b3a8eb9SGleb Smirnoff return (((caddr_t)prev) + bs); 451*3b3a8eb9SGleb Smirnoff } 452*3b3a8eb9SGleb Smirnoff 453*3b3a8eb9SGleb Smirnoff /* 454*3b3a8eb9SGleb Smirnoff * minsize: 455*3b3a8eb9SGleb Smirnoff * 0: make the buffer somewhat bigger 456*3b3a8eb9SGleb Smirnoff * n: make room for "n" entries in the buffer 457*3b3a8eb9SGleb Smirnoff */ 458*3b3a8eb9SGleb Smirnoff int 459*3b3a8eb9SGleb Smirnoff pfr_buf_grow(struct pfr_buffer *b, int minsize) 460*3b3a8eb9SGleb Smirnoff { 461*3b3a8eb9SGleb Smirnoff caddr_t p; 462*3b3a8eb9SGleb Smirnoff size_t bs; 463*3b3a8eb9SGleb Smirnoff 464*3b3a8eb9SGleb Smirnoff if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) { 465*3b3a8eb9SGleb Smirnoff errno = EINVAL; 466*3b3a8eb9SGleb Smirnoff return (-1); 467*3b3a8eb9SGleb Smirnoff } 468*3b3a8eb9SGleb Smirnoff if (minsize != 0 && minsize <= b->pfrb_msize) 469*3b3a8eb9SGleb Smirnoff return (0); 470*3b3a8eb9SGleb Smirnoff bs = buf_esize[b->pfrb_type]; 471*3b3a8eb9SGleb Smirnoff if (!b->pfrb_msize) { 472*3b3a8eb9SGleb Smirnoff if (minsize < 64) 473*3b3a8eb9SGleb Smirnoff minsize = 64; 474*3b3a8eb9SGleb Smirnoff b->pfrb_caddr = calloc(bs, minsize); 475*3b3a8eb9SGleb Smirnoff if (b->pfrb_caddr == NULL) 476*3b3a8eb9SGleb Smirnoff return (-1); 477*3b3a8eb9SGleb Smirnoff b->pfrb_msize = minsize; 478*3b3a8eb9SGleb Smirnoff } else { 479*3b3a8eb9SGleb Smirnoff if (minsize == 0) 480*3b3a8eb9SGleb Smirnoff minsize = b->pfrb_msize * 2; 481*3b3a8eb9SGleb Smirnoff if (minsize < 0 || minsize >= SIZE_T_MAX / bs) { 482*3b3a8eb9SGleb Smirnoff /* msize overflow */ 483*3b3a8eb9SGleb Smirnoff errno = ENOMEM; 484*3b3a8eb9SGleb Smirnoff return (-1); 485*3b3a8eb9SGleb Smirnoff } 486*3b3a8eb9SGleb Smirnoff p = realloc(b->pfrb_caddr, minsize * bs); 487*3b3a8eb9SGleb Smirnoff if (p == NULL) 488*3b3a8eb9SGleb Smirnoff return (-1); 489*3b3a8eb9SGleb Smirnoff bzero(p + b->pfrb_msize * bs, (minsize - b->pfrb_msize) * bs); 490*3b3a8eb9SGleb Smirnoff b->pfrb_caddr = p; 491*3b3a8eb9SGleb Smirnoff b->pfrb_msize = minsize; 492*3b3a8eb9SGleb Smirnoff } 493*3b3a8eb9SGleb Smirnoff return (0); 494*3b3a8eb9SGleb Smirnoff } 495*3b3a8eb9SGleb Smirnoff 496*3b3a8eb9SGleb Smirnoff /* 497*3b3a8eb9SGleb Smirnoff * reset buffer and free memory. 498*3b3a8eb9SGleb Smirnoff */ 499*3b3a8eb9SGleb Smirnoff void 500*3b3a8eb9SGleb Smirnoff pfr_buf_clear(struct pfr_buffer *b) 501*3b3a8eb9SGleb Smirnoff { 502*3b3a8eb9SGleb Smirnoff if (b == NULL) 503*3b3a8eb9SGleb Smirnoff return; 504*3b3a8eb9SGleb Smirnoff if (b->pfrb_caddr != NULL) 505*3b3a8eb9SGleb Smirnoff free(b->pfrb_caddr); 506*3b3a8eb9SGleb Smirnoff b->pfrb_caddr = NULL; 507*3b3a8eb9SGleb Smirnoff b->pfrb_size = b->pfrb_msize = 0; 508*3b3a8eb9SGleb Smirnoff } 509*3b3a8eb9SGleb Smirnoff 510*3b3a8eb9SGleb Smirnoff int 511*3b3a8eb9SGleb Smirnoff pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork, 512*3b3a8eb9SGleb Smirnoff int (*append_addr)(struct pfr_buffer *, char *, int)) 513*3b3a8eb9SGleb Smirnoff { 514*3b3a8eb9SGleb Smirnoff FILE *fp; 515*3b3a8eb9SGleb Smirnoff char buf[BUF_SIZE]; 516*3b3a8eb9SGleb Smirnoff int rv; 517*3b3a8eb9SGleb Smirnoff 518*3b3a8eb9SGleb Smirnoff if (file == NULL) 519*3b3a8eb9SGleb Smirnoff return (0); 520*3b3a8eb9SGleb Smirnoff if (!strcmp(file, "-")) 521*3b3a8eb9SGleb Smirnoff fp = stdin; 522*3b3a8eb9SGleb Smirnoff else { 523*3b3a8eb9SGleb Smirnoff fp = pfctl_fopen(file, "r"); 524*3b3a8eb9SGleb Smirnoff if (fp == NULL) 525*3b3a8eb9SGleb Smirnoff return (-1); 526*3b3a8eb9SGleb Smirnoff } 527*3b3a8eb9SGleb Smirnoff while ((rv = pfr_next_token(buf, fp)) == 1) 528*3b3a8eb9SGleb Smirnoff if (append_addr(b, buf, nonetwork)) { 529*3b3a8eb9SGleb Smirnoff rv = -1; 530*3b3a8eb9SGleb Smirnoff break; 531*3b3a8eb9SGleb Smirnoff } 532*3b3a8eb9SGleb Smirnoff if (fp != stdin) 533*3b3a8eb9SGleb Smirnoff fclose(fp); 534*3b3a8eb9SGleb Smirnoff return (rv); 535*3b3a8eb9SGleb Smirnoff } 536*3b3a8eb9SGleb Smirnoff 537*3b3a8eb9SGleb Smirnoff int 538*3b3a8eb9SGleb Smirnoff pfr_next_token(char buf[BUF_SIZE], FILE *fp) 539*3b3a8eb9SGleb Smirnoff { 540*3b3a8eb9SGleb Smirnoff static char next_ch = ' '; 541*3b3a8eb9SGleb Smirnoff int i = 0; 542*3b3a8eb9SGleb Smirnoff 543*3b3a8eb9SGleb Smirnoff for (;;) { 544*3b3a8eb9SGleb Smirnoff /* skip spaces */ 545*3b3a8eb9SGleb Smirnoff while (isspace(next_ch) && !feof(fp)) 546*3b3a8eb9SGleb Smirnoff next_ch = fgetc(fp); 547*3b3a8eb9SGleb Smirnoff /* remove from '#' until end of line */ 548*3b3a8eb9SGleb Smirnoff if (next_ch == '#') 549*3b3a8eb9SGleb Smirnoff while (!feof(fp)) { 550*3b3a8eb9SGleb Smirnoff next_ch = fgetc(fp); 551*3b3a8eb9SGleb Smirnoff if (next_ch == '\n') 552*3b3a8eb9SGleb Smirnoff break; 553*3b3a8eb9SGleb Smirnoff } 554*3b3a8eb9SGleb Smirnoff else 555*3b3a8eb9SGleb Smirnoff break; 556*3b3a8eb9SGleb Smirnoff } 557*3b3a8eb9SGleb Smirnoff if (feof(fp)) { 558*3b3a8eb9SGleb Smirnoff next_ch = ' '; 559*3b3a8eb9SGleb Smirnoff return (0); 560*3b3a8eb9SGleb Smirnoff } 561*3b3a8eb9SGleb Smirnoff do { 562*3b3a8eb9SGleb Smirnoff if (i < BUF_SIZE) 563*3b3a8eb9SGleb Smirnoff buf[i++] = next_ch; 564*3b3a8eb9SGleb Smirnoff next_ch = fgetc(fp); 565*3b3a8eb9SGleb Smirnoff } while (!feof(fp) && !isspace(next_ch)); 566*3b3a8eb9SGleb Smirnoff if (i >= BUF_SIZE) { 567*3b3a8eb9SGleb Smirnoff errno = EINVAL; 568*3b3a8eb9SGleb Smirnoff return (-1); 569*3b3a8eb9SGleb Smirnoff } 570*3b3a8eb9SGleb Smirnoff buf[i] = '\0'; 571*3b3a8eb9SGleb Smirnoff return (1); 572*3b3a8eb9SGleb Smirnoff } 573*3b3a8eb9SGleb Smirnoff 574*3b3a8eb9SGleb Smirnoff char * 575*3b3a8eb9SGleb Smirnoff pfr_strerror(int errnum) 576*3b3a8eb9SGleb Smirnoff { 577*3b3a8eb9SGleb Smirnoff switch (errnum) { 578*3b3a8eb9SGleb Smirnoff case ESRCH: 579*3b3a8eb9SGleb Smirnoff return "Table does not exist"; 580*3b3a8eb9SGleb Smirnoff case ENOENT: 581*3b3a8eb9SGleb Smirnoff return "Anchor or Ruleset does not exist"; 582*3b3a8eb9SGleb Smirnoff default: 583*3b3a8eb9SGleb Smirnoff return strerror(errnum); 584*3b3a8eb9SGleb Smirnoff } 585*3b3a8eb9SGleb Smirnoff } 586