1171169Smlaier/* $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */ 2126353Smlaier 3126353Smlaier/* 4126353Smlaier * Copyright (c) 2002 Cedric Berger 5126353Smlaier * All rights reserved. 6126353Smlaier * 7126353Smlaier * Redistribution and use in source and binary forms, with or without 8126353Smlaier * modification, are permitted provided that the following conditions 9126353Smlaier * are met: 10126353Smlaier * 11126353Smlaier * - Redistributions of source code must retain the above copyright 12126353Smlaier * notice, this list of conditions and the following disclaimer. 13126353Smlaier * - Redistributions in binary form must reproduce the above 14126353Smlaier * copyright notice, this list of conditions and the following 15126353Smlaier * disclaimer in the documentation and/or other materials provided 16126353Smlaier * with the distribution. 17126353Smlaier * 18126353Smlaier * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19126353Smlaier * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20126353Smlaier * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21126353Smlaier * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22126353Smlaier * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23126353Smlaier * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24126353Smlaier * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25126353Smlaier * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26126353Smlaier * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27126353Smlaier * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28126353Smlaier * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29126353Smlaier * POSSIBILITY OF SUCH DAMAGE. 30126353Smlaier * 31126353Smlaier */ 32126353Smlaier 33223637Sbz#include <sys/cdefs.h> 34223637Sbz__FBSDID("$FreeBSD$"); 35223637Sbz 36126353Smlaier#include <sys/types.h> 37126353Smlaier#include <sys/ioctl.h> 38126353Smlaier#include <sys/socket.h> 39126353Smlaier 40126353Smlaier#include <net/if.h> 41126353Smlaier#include <net/pfvar.h> 42126353Smlaier 43126353Smlaier#include <errno.h> 44126353Smlaier#include <string.h> 45126353Smlaier#include <ctype.h> 46126353Smlaier#include <stdio.h> 47126353Smlaier#include <stdlib.h> 48126353Smlaier#include <limits.h> 49126353Smlaier#include <err.h> 50126353Smlaier 51126353Smlaier#include "pfctl.h" 52126353Smlaier 53126353Smlaier#define BUF_SIZE 256 54126353Smlaier 55126353Smlaierextern int dev; 56126353Smlaier 57126353Smlaierstatic int pfr_next_token(char buf[], FILE *); 58126353Smlaier 59126353Smlaier 60126353Smlaierint 61126353Smlaierpfr_clr_tables(struct pfr_table *filter, int *ndel, int flags) 62126353Smlaier{ 63126353Smlaier struct pfioc_table io; 64126353Smlaier 65126353Smlaier bzero(&io, sizeof io); 66126353Smlaier io.pfrio_flags = flags; 67126353Smlaier if (filter != NULL) 68126353Smlaier io.pfrio_table = *filter; 69126353Smlaier if (ioctl(dev, DIOCRCLRTABLES, &io)) 70126353Smlaier return (-1); 71126353Smlaier if (ndel != NULL) 72126353Smlaier *ndel = io.pfrio_ndel; 73126353Smlaier return (0); 74126353Smlaier} 75126353Smlaier 76126353Smlaierint 77126353Smlaierpfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) 78126353Smlaier{ 79126353Smlaier struct pfioc_table io; 80126353Smlaier 81126353Smlaier if (size < 0 || (size && tbl == NULL)) { 82126353Smlaier errno = EINVAL; 83126353Smlaier return (-1); 84126353Smlaier } 85126353Smlaier bzero(&io, sizeof io); 86126353Smlaier io.pfrio_flags = flags; 87126353Smlaier io.pfrio_buffer = tbl; 88126353Smlaier io.pfrio_esize = sizeof(*tbl); 89126353Smlaier io.pfrio_size = size; 90126353Smlaier if (ioctl(dev, DIOCRADDTABLES, &io)) 91126353Smlaier return (-1); 92126353Smlaier if (nadd != NULL) 93126353Smlaier *nadd = io.pfrio_nadd; 94126353Smlaier return (0); 95126353Smlaier} 96126353Smlaier 97126353Smlaierint 98126353Smlaierpfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags) 99126353Smlaier{ 100126353Smlaier struct pfioc_table io; 101126353Smlaier 102126353Smlaier if (size < 0 || (size && tbl == NULL)) { 103126353Smlaier errno = EINVAL; 104126353Smlaier return (-1); 105126353Smlaier } 106126353Smlaier bzero(&io, sizeof io); 107126353Smlaier io.pfrio_flags = flags; 108126353Smlaier io.pfrio_buffer = tbl; 109126353Smlaier io.pfrio_esize = sizeof(*tbl); 110126353Smlaier io.pfrio_size = size; 111126353Smlaier if (ioctl(dev, DIOCRDELTABLES, &io)) 112126353Smlaier return (-1); 113126353Smlaier if (ndel != NULL) 114126353Smlaier *ndel = io.pfrio_ndel; 115126353Smlaier return (0); 116126353Smlaier} 117126353Smlaier 118126353Smlaierint 119126353Smlaierpfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size, 120126353Smlaier int flags) 121126353Smlaier{ 122126353Smlaier struct pfioc_table io; 123126353Smlaier 124126353Smlaier if (size == NULL || *size < 0 || (*size && tbl == NULL)) { 125126353Smlaier errno = EINVAL; 126126353Smlaier return (-1); 127126353Smlaier } 128126353Smlaier bzero(&io, sizeof io); 129126353Smlaier io.pfrio_flags = flags; 130126353Smlaier if (filter != NULL) 131126353Smlaier io.pfrio_table = *filter; 132126353Smlaier io.pfrio_buffer = tbl; 133126353Smlaier io.pfrio_esize = sizeof(*tbl); 134126353Smlaier io.pfrio_size = *size; 135126353Smlaier if (ioctl(dev, DIOCRGETTABLES, &io)) 136126353Smlaier return (-1); 137126353Smlaier *size = io.pfrio_size; 138126353Smlaier return (0); 139126353Smlaier} 140126353Smlaier 141126353Smlaierint 142126353Smlaierpfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, 143126353Smlaier int flags) 144126353Smlaier{ 145126353Smlaier struct pfioc_table io; 146126353Smlaier 147126353Smlaier if (size == NULL || *size < 0 || (*size && tbl == NULL)) { 148126353Smlaier errno = EINVAL; 149126353Smlaier return (-1); 150126353Smlaier } 151126353Smlaier bzero(&io, sizeof io); 152126353Smlaier io.pfrio_flags = flags; 153126353Smlaier if (filter != NULL) 154126353Smlaier io.pfrio_table = *filter; 155126353Smlaier io.pfrio_buffer = tbl; 156126353Smlaier io.pfrio_esize = sizeof(*tbl); 157126353Smlaier io.pfrio_size = *size; 158126353Smlaier if (ioctl(dev, DIOCRGETTSTATS, &io)) 159126353Smlaier return (-1); 160126353Smlaier *size = io.pfrio_size; 161126353Smlaier return (0); 162126353Smlaier} 163126353Smlaier 164126353Smlaierint 165126353Smlaierpfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags) 166126353Smlaier{ 167126353Smlaier struct pfioc_table io; 168126353Smlaier 169126353Smlaier if (tbl == NULL) { 170126353Smlaier errno = EINVAL; 171126353Smlaier return (-1); 172126353Smlaier } 173126353Smlaier bzero(&io, sizeof io); 174126353Smlaier io.pfrio_flags = flags; 175126353Smlaier io.pfrio_table = *tbl; 176126353Smlaier if (ioctl(dev, DIOCRCLRADDRS, &io)) 177126353Smlaier return (-1); 178126353Smlaier if (ndel != NULL) 179126353Smlaier *ndel = io.pfrio_ndel; 180126353Smlaier return (0); 181126353Smlaier} 182126353Smlaier 183126353Smlaierint 184126353Smlaierpfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 185126353Smlaier int *nadd, int flags) 186126353Smlaier{ 187126353Smlaier struct pfioc_table io; 188126353Smlaier 189126353Smlaier if (tbl == NULL || size < 0 || (size && addr == NULL)) { 190126353Smlaier errno = EINVAL; 191126353Smlaier return (-1); 192126353Smlaier } 193126353Smlaier bzero(&io, sizeof io); 194126353Smlaier io.pfrio_flags = flags; 195126353Smlaier io.pfrio_table = *tbl; 196126353Smlaier io.pfrio_buffer = addr; 197126353Smlaier io.pfrio_esize = sizeof(*addr); 198126353Smlaier io.pfrio_size = size; 199126353Smlaier if (ioctl(dev, DIOCRADDADDRS, &io)) 200126353Smlaier return (-1); 201126353Smlaier if (nadd != NULL) 202126353Smlaier *nadd = io.pfrio_nadd; 203126353Smlaier return (0); 204126353Smlaier} 205126353Smlaier 206126353Smlaierint 207126353Smlaierpfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 208126353Smlaier int *ndel, int flags) 209126353Smlaier{ 210126353Smlaier struct pfioc_table io; 211126353Smlaier 212126353Smlaier if (tbl == NULL || size < 0 || (size && addr == NULL)) { 213126353Smlaier errno = EINVAL; 214126353Smlaier return (-1); 215126353Smlaier } 216126353Smlaier bzero(&io, sizeof io); 217126353Smlaier io.pfrio_flags = flags; 218126353Smlaier io.pfrio_table = *tbl; 219126353Smlaier io.pfrio_buffer = addr; 220126353Smlaier io.pfrio_esize = sizeof(*addr); 221126353Smlaier io.pfrio_size = size; 222126353Smlaier if (ioctl(dev, DIOCRDELADDRS, &io)) 223126353Smlaier return (-1); 224126353Smlaier if (ndel != NULL) 225126353Smlaier *ndel = io.pfrio_ndel; 226126353Smlaier return (0); 227126353Smlaier} 228126353Smlaier 229126353Smlaierint 230126353Smlaierpfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 231126353Smlaier int *size2, int *nadd, int *ndel, int *nchange, int flags) 232126353Smlaier{ 233126353Smlaier struct pfioc_table io; 234126353Smlaier 235126353Smlaier if (tbl == NULL || size < 0 || (size && addr == NULL)) { 236126353Smlaier errno = EINVAL; 237126353Smlaier return (-1); 238126353Smlaier } 239126353Smlaier bzero(&io, sizeof io); 240126353Smlaier io.pfrio_flags = flags; 241126353Smlaier io.pfrio_table = *tbl; 242126353Smlaier io.pfrio_buffer = addr; 243126353Smlaier io.pfrio_esize = sizeof(*addr); 244126353Smlaier io.pfrio_size = size; 245126353Smlaier io.pfrio_size2 = (size2 != NULL) ? *size2 : 0; 246126353Smlaier if (ioctl(dev, DIOCRSETADDRS, &io)) 247126353Smlaier return (-1); 248126353Smlaier if (nadd != NULL) 249126353Smlaier *nadd = io.pfrio_nadd; 250126353Smlaier if (ndel != NULL) 251126353Smlaier *ndel = io.pfrio_ndel; 252126353Smlaier if (nchange != NULL) 253126353Smlaier *nchange = io.pfrio_nchange; 254126353Smlaier if (size2 != NULL) 255126353Smlaier *size2 = io.pfrio_size2; 256126353Smlaier return (0); 257126353Smlaier} 258126353Smlaier 259126353Smlaierint 260126353Smlaierpfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size, 261126353Smlaier int flags) 262126353Smlaier{ 263126353Smlaier struct pfioc_table io; 264126353Smlaier 265130614Smlaier if (tbl == NULL || size == NULL || *size < 0 || 266130614Smlaier (*size && addr == NULL)) { 267126353Smlaier errno = EINVAL; 268126353Smlaier return (-1); 269126353Smlaier } 270126353Smlaier bzero(&io, sizeof io); 271126353Smlaier io.pfrio_flags = flags; 272126353Smlaier io.pfrio_table = *tbl; 273126353Smlaier io.pfrio_buffer = addr; 274126353Smlaier io.pfrio_esize = sizeof(*addr); 275126353Smlaier io.pfrio_size = *size; 276126353Smlaier if (ioctl(dev, DIOCRGETADDRS, &io)) 277126353Smlaier return (-1); 278126353Smlaier *size = io.pfrio_size; 279126353Smlaier return (0); 280126353Smlaier} 281126353Smlaier 282126353Smlaierint 283126353Smlaierpfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, 284126353Smlaier int flags) 285126353Smlaier{ 286126353Smlaier struct pfioc_table io; 287126353Smlaier 288130614Smlaier if (tbl == NULL || size == NULL || *size < 0 || 289130614Smlaier (*size && addr == NULL)) { 290126353Smlaier errno = EINVAL; 291126353Smlaier return (-1); 292126353Smlaier } 293126353Smlaier bzero(&io, sizeof io); 294126353Smlaier io.pfrio_flags = flags; 295126353Smlaier io.pfrio_table = *tbl; 296126353Smlaier io.pfrio_buffer = addr; 297126353Smlaier io.pfrio_esize = sizeof(*addr); 298126353Smlaier io.pfrio_size = *size; 299126353Smlaier if (ioctl(dev, DIOCRGETASTATS, &io)) 300126353Smlaier return (-1); 301126353Smlaier *size = io.pfrio_size; 302126353Smlaier return (0); 303126353Smlaier} 304126353Smlaier 305126353Smlaierint 306126353Smlaierpfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) 307126353Smlaier{ 308126353Smlaier struct pfioc_table io; 309126353Smlaier 310126353Smlaier if (size < 0 || (size && !tbl)) { 311126353Smlaier errno = EINVAL; 312126353Smlaier return (-1); 313126353Smlaier } 314126353Smlaier bzero(&io, sizeof io); 315126353Smlaier io.pfrio_flags = flags; 316126353Smlaier io.pfrio_buffer = tbl; 317126353Smlaier io.pfrio_esize = sizeof(*tbl); 318126353Smlaier io.pfrio_size = size; 319126353Smlaier if (ioctl(dev, DIOCRCLRTSTATS, &io)) 320126353Smlaier return (-1); 321126353Smlaier if (nzero) 322126353Smlaier *nzero = io.pfrio_nzero; 323126353Smlaier return (0); 324126353Smlaier} 325126353Smlaier 326126353Smlaierint 327126353Smlaierpfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, 328126353Smlaier int *nmatch, int flags) 329126353Smlaier{ 330126353Smlaier struct pfioc_table io; 331126353Smlaier 332126353Smlaier if (tbl == NULL || size < 0 || (size && addr == NULL)) { 333126353Smlaier errno = EINVAL; 334126353Smlaier return (-1); 335126353Smlaier } 336126353Smlaier bzero(&io, sizeof io); 337126353Smlaier io.pfrio_flags = flags; 338126353Smlaier io.pfrio_table = *tbl; 339126353Smlaier io.pfrio_buffer = addr; 340126353Smlaier io.pfrio_esize = sizeof(*addr); 341126353Smlaier io.pfrio_size = size; 342126353Smlaier if (ioctl(dev, DIOCRTSTADDRS, &io)) 343126353Smlaier return (-1); 344126353Smlaier if (nmatch) 345126353Smlaier *nmatch = io.pfrio_nmatch; 346126353Smlaier return (0); 347126353Smlaier} 348126353Smlaier 349126353Smlaierint 350126353Smlaierpfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, 351126353Smlaier int *nadd, int *naddr, int ticket, int flags) 352126353Smlaier{ 353126353Smlaier struct pfioc_table io; 354126353Smlaier 355126353Smlaier if (tbl == NULL || size < 0 || (size && addr == NULL)) { 356126353Smlaier errno = EINVAL; 357126353Smlaier return (-1); 358126353Smlaier } 359126353Smlaier bzero(&io, sizeof io); 360126353Smlaier io.pfrio_flags = flags; 361126353Smlaier io.pfrio_table = *tbl; 362126353Smlaier io.pfrio_buffer = addr; 363126353Smlaier io.pfrio_esize = sizeof(*addr); 364126353Smlaier io.pfrio_size = size; 365126353Smlaier io.pfrio_ticket = ticket; 366126353Smlaier if (ioctl(dev, DIOCRINADEFINE, &io)) 367126353Smlaier return (-1); 368126353Smlaier if (nadd != NULL) 369126353Smlaier *nadd = io.pfrio_nadd; 370126353Smlaier if (naddr != NULL) 371126353Smlaier *naddr = io.pfrio_naddr; 372126353Smlaier return (0); 373126353Smlaier} 374126353Smlaier 375130614Smlaier/* interface management code */ 376130614Smlaier 377130614Smlaierint 378171169Smlaierpfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size) 379130614Smlaier{ 380130614Smlaier struct pfioc_iface io; 381130614Smlaier 382130614Smlaier if (size == NULL || *size < 0 || (*size && buf == NULL)) { 383130614Smlaier errno = EINVAL; 384130614Smlaier return (-1); 385130614Smlaier } 386130614Smlaier bzero(&io, sizeof io); 387130614Smlaier if (filter != NULL) 388130614Smlaier if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >= 389130614Smlaier sizeof(io.pfiio_name)) { 390130614Smlaier errno = EINVAL; 391130614Smlaier return (-1); 392130614Smlaier } 393130614Smlaier io.pfiio_buffer = buf; 394130614Smlaier io.pfiio_esize = sizeof(*buf); 395130614Smlaier io.pfiio_size = *size; 396130614Smlaier if (ioctl(dev, DIOCIGETIFACES, &io)) 397130614Smlaier return (-1); 398130614Smlaier *size = io.pfiio_size; 399130614Smlaier return (0); 400130614Smlaier} 401130614Smlaier 402126353Smlaier/* buffer management code */ 403126353Smlaier 404126353Smlaiersize_t buf_esize[PFRB_MAX] = { 0, 405126353Smlaier sizeof(struct pfr_table), sizeof(struct pfr_tstats), 406126353Smlaier sizeof(struct pfr_addr), sizeof(struct pfr_astats), 407171169Smlaier sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e) 408126353Smlaier}; 409126353Smlaier 410126353Smlaier/* 411126353Smlaier * add one element to the buffer 412126353Smlaier */ 413126353Smlaierint 414126353Smlaierpfr_buf_add(struct pfr_buffer *b, const void *e) 415126353Smlaier{ 416126353Smlaier size_t bs; 417126353Smlaier 418126353Smlaier if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX || 419126353Smlaier e == NULL) { 420126353Smlaier errno = EINVAL; 421126353Smlaier return (-1); 422126353Smlaier } 423126353Smlaier bs = buf_esize[b->pfrb_type]; 424126353Smlaier if (b->pfrb_size == b->pfrb_msize) 425126353Smlaier if (pfr_buf_grow(b, 0)) 426126353Smlaier return (-1); 427126353Smlaier memcpy(((caddr_t)b->pfrb_caddr) + bs * b->pfrb_size, e, bs); 428126353Smlaier b->pfrb_size++; 429126353Smlaier return (0); 430126353Smlaier} 431126353Smlaier 432126353Smlaier/* 433126353Smlaier * return next element of the buffer (or first one if prev is NULL) 434126353Smlaier * see PFRB_FOREACH macro 435126353Smlaier */ 436126353Smlaiervoid * 437126353Smlaierpfr_buf_next(struct pfr_buffer *b, const void *prev) 438126353Smlaier{ 439126353Smlaier size_t bs; 440126353Smlaier 441126353Smlaier if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) 442126353Smlaier return (NULL); 443126353Smlaier if (b->pfrb_size == 0) 444126353Smlaier return (NULL); 445126353Smlaier if (prev == NULL) 446126353Smlaier return (b->pfrb_caddr); 447126353Smlaier bs = buf_esize[b->pfrb_type]; 448126353Smlaier if ((((caddr_t)prev)-((caddr_t)b->pfrb_caddr)) / bs >= b->pfrb_size-1) 449126353Smlaier return (NULL); 450126353Smlaier return (((caddr_t)prev) + bs); 451126353Smlaier} 452126353Smlaier 453126353Smlaier/* 454126353Smlaier * minsize: 455126353Smlaier * 0: make the buffer somewhat bigger 456126353Smlaier * n: make room for "n" entries in the buffer 457126353Smlaier */ 458126353Smlaierint 459126353Smlaierpfr_buf_grow(struct pfr_buffer *b, int minsize) 460126353Smlaier{ 461126353Smlaier caddr_t p; 462126353Smlaier size_t bs; 463126353Smlaier 464126353Smlaier if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) { 465126353Smlaier errno = EINVAL; 466126353Smlaier return (-1); 467126353Smlaier } 468126353Smlaier if (minsize != 0 && minsize <= b->pfrb_msize) 469126353Smlaier return (0); 470126353Smlaier bs = buf_esize[b->pfrb_type]; 471126353Smlaier if (!b->pfrb_msize) { 472126353Smlaier if (minsize < 64) 473126353Smlaier minsize = 64; 474126353Smlaier b->pfrb_caddr = calloc(bs, minsize); 475126353Smlaier if (b->pfrb_caddr == NULL) 476126353Smlaier return (-1); 477126353Smlaier b->pfrb_msize = minsize; 478126353Smlaier } else { 479126353Smlaier if (minsize == 0) 480126353Smlaier minsize = b->pfrb_msize * 2; 481126353Smlaier if (minsize < 0 || minsize >= SIZE_T_MAX / bs) { 482126353Smlaier /* msize overflow */ 483126353Smlaier errno = ENOMEM; 484126353Smlaier return (-1); 485126353Smlaier } 486126353Smlaier p = realloc(b->pfrb_caddr, minsize * bs); 487126353Smlaier if (p == NULL) 488126353Smlaier return (-1); 489126353Smlaier bzero(p + b->pfrb_msize * bs, (minsize - b->pfrb_msize) * bs); 490126353Smlaier b->pfrb_caddr = p; 491126353Smlaier b->pfrb_msize = minsize; 492126353Smlaier } 493126353Smlaier return (0); 494126353Smlaier} 495126353Smlaier 496126353Smlaier/* 497126353Smlaier * reset buffer and free memory. 498126353Smlaier */ 499126353Smlaiervoid 500126353Smlaierpfr_buf_clear(struct pfr_buffer *b) 501126353Smlaier{ 502126353Smlaier if (b == NULL) 503126353Smlaier return; 504126353Smlaier if (b->pfrb_caddr != NULL) 505126353Smlaier free(b->pfrb_caddr); 506126353Smlaier b->pfrb_caddr = NULL; 507126353Smlaier b->pfrb_size = b->pfrb_msize = 0; 508126353Smlaier} 509126353Smlaier 510126353Smlaierint 511126353Smlaierpfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork, 512126353Smlaier int (*append_addr)(struct pfr_buffer *, char *, int)) 513126353Smlaier{ 514126353Smlaier FILE *fp; 515126353Smlaier char buf[BUF_SIZE]; 516126353Smlaier int rv; 517126353Smlaier 518126353Smlaier if (file == NULL) 519126353Smlaier return (0); 520126353Smlaier if (!strcmp(file, "-")) 521126353Smlaier fp = stdin; 522126353Smlaier else { 523145837Smlaier fp = pfctl_fopen(file, "r"); 524126353Smlaier if (fp == NULL) 525126353Smlaier return (-1); 526126353Smlaier } 527126353Smlaier while ((rv = pfr_next_token(buf, fp)) == 1) 528126353Smlaier if (append_addr(b, buf, nonetwork)) { 529126353Smlaier rv = -1; 530126353Smlaier break; 531126353Smlaier } 532126353Smlaier if (fp != stdin) 533126353Smlaier fclose(fp); 534126353Smlaier return (rv); 535126353Smlaier} 536126353Smlaier 537126353Smlaierint 538126353Smlaierpfr_next_token(char buf[BUF_SIZE], FILE *fp) 539126353Smlaier{ 540126353Smlaier static char next_ch = ' '; 541126353Smlaier int i = 0; 542126353Smlaier 543126353Smlaier for (;;) { 544126353Smlaier /* skip spaces */ 545126353Smlaier while (isspace(next_ch) && !feof(fp)) 546126353Smlaier next_ch = fgetc(fp); 547126353Smlaier /* remove from '#' until end of line */ 548126353Smlaier if (next_ch == '#') 549126353Smlaier while (!feof(fp)) { 550126353Smlaier next_ch = fgetc(fp); 551126353Smlaier if (next_ch == '\n') 552126353Smlaier break; 553126353Smlaier } 554126353Smlaier else 555126353Smlaier break; 556126353Smlaier } 557126353Smlaier if (feof(fp)) { 558126353Smlaier next_ch = ' '; 559126353Smlaier return (0); 560126353Smlaier } 561126353Smlaier do { 562126353Smlaier if (i < BUF_SIZE) 563126353Smlaier buf[i++] = next_ch; 564126353Smlaier next_ch = fgetc(fp); 565126353Smlaier } while (!feof(fp) && !isspace(next_ch)); 566126353Smlaier if (i >= BUF_SIZE) { 567126353Smlaier errno = EINVAL; 568126353Smlaier return (-1); 569126353Smlaier } 570126353Smlaier buf[i] = '\0'; 571126353Smlaier return (1); 572126353Smlaier} 573126353Smlaier 574126353Smlaierchar * 575126353Smlaierpfr_strerror(int errnum) 576126353Smlaier{ 577126353Smlaier switch (errnum) { 578126353Smlaier case ESRCH: 579126353Smlaier return "Table does not exist"; 580126353Smlaier case ENOENT: 581126353Smlaier return "Anchor or Ruleset does not exist"; 582126353Smlaier default: 583126353Smlaier return strerror(errnum); 584126353Smlaier } 585126353Smlaier} 586