1/* $OpenBSD: pfctl_table.c,v 1.62 2004/12/22 17:17:55 dhartmei Exp $ */
| 1/* $OpenBSD: pfctl_table.c,v 1.66 2007/03/01 17:20:54 deraadt Exp $ */
|
2 3/* 4 * Copyright (c) 2002 Cedric Berger 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 33#include <sys/cdefs.h>
| 2 3/* 4 * Copyright (c) 2002 Cedric Berger 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 33#include <sys/cdefs.h>
|
34__FBSDID("$FreeBSD: head/contrib/pf/pfctl/pfctl_table.c 145840 2005-05-03 16:55:20Z mlaier $");
| 34__FBSDID("$FreeBSD: head/contrib/pf/pfctl/pfctl_table.c 171172 2007-07-03 12:30:03Z mlaier $");
|
35 36#include <sys/types.h> 37#include <sys/ioctl.h> 38#include <sys/socket.h> 39 40#include <net/if.h> 41#include <net/pfvar.h> 42#include <arpa/inet.h> 43 44#include <ctype.h> 45#include <err.h> 46#include <errno.h> 47#include <netdb.h> 48#include <stdarg.h> 49#include <stdio.h> 50#include <stdlib.h> 51#include <string.h> 52#include <time.h> 53 54#include "pfctl_parser.h" 55#include "pfctl.h" 56 57extern void usage(void); 58static int pfctl_table(int, char *[], char *, const char *, char *, 59 const char *, int); 60static void print_table(struct pfr_table *, int, int); 61static void print_tstats(struct pfr_tstats *, int); 62static int load_addr(struct pfr_buffer *, int, char *[], char *, int); 63static void print_addrx(struct pfr_addr *, struct pfr_addr *, int); 64static void print_astats(struct pfr_astats *, int); 65static void radix_perror(void); 66static void xprintf(int, const char *, ...);
| 35 36#include <sys/types.h> 37#include <sys/ioctl.h> 38#include <sys/socket.h> 39 40#include <net/if.h> 41#include <net/pfvar.h> 42#include <arpa/inet.h> 43 44#include <ctype.h> 45#include <err.h> 46#include <errno.h> 47#include <netdb.h> 48#include <stdarg.h> 49#include <stdio.h> 50#include <stdlib.h> 51#include <string.h> 52#include <time.h> 53 54#include "pfctl_parser.h" 55#include "pfctl.h" 56 57extern void usage(void); 58static int pfctl_table(int, char *[], char *, const char *, char *, 59 const char *, int); 60static void print_table(struct pfr_table *, int, int); 61static void print_tstats(struct pfr_tstats *, int); 62static int load_addr(struct pfr_buffer *, int, char *[], char *, int); 63static void print_addrx(struct pfr_addr *, struct pfr_addr *, int); 64static void print_astats(struct pfr_astats *, int); 65static void radix_perror(void); 66static void xprintf(int, const char *, ...);
|
67static void print_iface(struct pfi_if *, int); 68static void oprintf(int, int, const char *, int *, int);
| 67static void print_iface(struct pfi_kif *, int);
|
69 70static const char *stats_text[PFR_DIR_MAX][PFR_OP_TABLE_MAX] = { 71 { "In/Block:", "In/Pass:", "In/XPass:" }, 72 { "Out/Block:", "Out/Pass:", "Out/XPass:" } 73}; 74 75static const char *istats_text[2][2][2] = { 76 { { "In4/Pass:", "In4/Block:" }, { "Out4/Pass:", "Out4/Block:" } }, 77 { { "In6/Pass:", "In6/Block:" }, { "Out6/Pass:", "Out6/Block:" } } 78}; 79 80#define RVTEST(fct) do { \ 81 if ((!(opts & PF_OPT_NOACTION) || \ 82 (opts & PF_OPT_DUMMYACTION)) && \ 83 (fct)) { \ 84 radix_perror(); \ 85 goto _error; \ 86 } \ 87 } while (0) 88 89#define CREATE_TABLE do { \ 90 table.pfrt_flags |= PFR_TFLAG_PERSIST; \ 91 if ((!(opts & PF_OPT_NOACTION) || \ 92 (opts & PF_OPT_DUMMYACTION)) && \ 93 (pfr_add_tables(&table, 1, &nadd, flags)) && \ 94 (errno != EPERM)) { \ 95 radix_perror(); \ 96 goto _error; \ 97 } \ 98 if (nadd) { \ 99 warn_namespace_collision(table.pfrt_name); \ 100 xprintf(opts, "%d table created", nadd); \ 101 if (opts & PF_OPT_NOACTION) \ 102 return (0); \ 103 } \ 104 table.pfrt_flags &= ~PFR_TFLAG_PERSIST; \ 105 } while(0) 106 107int 108pfctl_clear_tables(const char *anchor, int opts) 109{ 110 return pfctl_table(0, NULL, NULL, "-F", NULL, anchor, opts); 111} 112 113int 114pfctl_show_tables(const char *anchor, int opts) 115{ 116 return pfctl_table(0, NULL, NULL, "-s", NULL, anchor, opts); 117} 118 119int 120pfctl_command_tables(int argc, char *argv[], char *tname, 121 const char *command, char *file, const char *anchor, int opts) 122{ 123 if (tname == NULL || command == NULL) 124 usage(); 125 return pfctl_table(argc, argv, tname, command, file, anchor, opts); 126} 127 128int 129pfctl_table(int argc, char *argv[], char *tname, const char *command, 130 char *file, const char *anchor, int opts) 131{ 132 struct pfr_table table; 133 struct pfr_buffer b, b2; 134 struct pfr_addr *a, *a2; 135 int nadd = 0, ndel = 0, nchange = 0, nzero = 0; 136 int rv = 0, flags = 0, nmatch = 0; 137 void *p; 138 139 if (command == NULL) 140 usage(); 141 if (opts & PF_OPT_NOACTION) 142 flags |= PFR_FLAG_DUMMY; 143 144 bzero(&b, sizeof(b)); 145 bzero(&b2, sizeof(b2)); 146 bzero(&table, sizeof(table)); 147 if (tname != NULL) { 148 if (strlen(tname) >= PF_TABLE_NAME_SIZE) 149 usage(); 150 if (strlcpy(table.pfrt_name, tname, 151 sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name)) 152 errx(1, "pfctl_table: strlcpy"); 153 } 154 if (strlcpy(table.pfrt_anchor, anchor, 155 sizeof(table.pfrt_anchor)) >= sizeof(table.pfrt_anchor)) 156 errx(1, "pfctl_table: strlcpy"); 157 158 if (!strcmp(command, "-F")) { 159 if (argc || file != NULL) 160 usage(); 161 RVTEST(pfr_clr_tables(&table, &ndel, flags)); 162 xprintf(opts, "%d tables deleted", ndel); 163 } else if (!strcmp(command, "-s")) { 164 b.pfrb_type = (opts & PF_OPT_VERBOSE2) ? 165 PFRB_TSTATS : PFRB_TABLES; 166 if (argc || file != NULL) 167 usage(); 168 for (;;) { 169 pfr_buf_grow(&b, b.pfrb_size); 170 b.pfrb_size = b.pfrb_msize; 171 if (opts & PF_OPT_VERBOSE2) 172 RVTEST(pfr_get_tstats(&table, 173 b.pfrb_caddr, &b.pfrb_size, flags)); 174 else 175 RVTEST(pfr_get_tables(&table, 176 b.pfrb_caddr, &b.pfrb_size, flags)); 177 if (b.pfrb_size <= b.pfrb_msize) 178 break; 179 } 180
| 68 69static const char *stats_text[PFR_DIR_MAX][PFR_OP_TABLE_MAX] = { 70 { "In/Block:", "In/Pass:", "In/XPass:" }, 71 { "Out/Block:", "Out/Pass:", "Out/XPass:" } 72}; 73 74static const char *istats_text[2][2][2] = { 75 { { "In4/Pass:", "In4/Block:" }, { "Out4/Pass:", "Out4/Block:" } }, 76 { { "In6/Pass:", "In6/Block:" }, { "Out6/Pass:", "Out6/Block:" } } 77}; 78 79#define RVTEST(fct) do { \ 80 if ((!(opts & PF_OPT_NOACTION) || \ 81 (opts & PF_OPT_DUMMYACTION)) && \ 82 (fct)) { \ 83 radix_perror(); \ 84 goto _error; \ 85 } \ 86 } while (0) 87 88#define CREATE_TABLE do { \ 89 table.pfrt_flags |= PFR_TFLAG_PERSIST; \ 90 if ((!(opts & PF_OPT_NOACTION) || \ 91 (opts & PF_OPT_DUMMYACTION)) && \ 92 (pfr_add_tables(&table, 1, &nadd, flags)) && \ 93 (errno != EPERM)) { \ 94 radix_perror(); \ 95 goto _error; \ 96 } \ 97 if (nadd) { \ 98 warn_namespace_collision(table.pfrt_name); \ 99 xprintf(opts, "%d table created", nadd); \ 100 if (opts & PF_OPT_NOACTION) \ 101 return (0); \ 102 } \ 103 table.pfrt_flags &= ~PFR_TFLAG_PERSIST; \ 104 } while(0) 105 106int 107pfctl_clear_tables(const char *anchor, int opts) 108{ 109 return pfctl_table(0, NULL, NULL, "-F", NULL, anchor, opts); 110} 111 112int 113pfctl_show_tables(const char *anchor, int opts) 114{ 115 return pfctl_table(0, NULL, NULL, "-s", NULL, anchor, opts); 116} 117 118int 119pfctl_command_tables(int argc, char *argv[], char *tname, 120 const char *command, char *file, const char *anchor, int opts) 121{ 122 if (tname == NULL || command == NULL) 123 usage(); 124 return pfctl_table(argc, argv, tname, command, file, anchor, opts); 125} 126 127int 128pfctl_table(int argc, char *argv[], char *tname, const char *command, 129 char *file, const char *anchor, int opts) 130{ 131 struct pfr_table table; 132 struct pfr_buffer b, b2; 133 struct pfr_addr *a, *a2; 134 int nadd = 0, ndel = 0, nchange = 0, nzero = 0; 135 int rv = 0, flags = 0, nmatch = 0; 136 void *p; 137 138 if (command == NULL) 139 usage(); 140 if (opts & PF_OPT_NOACTION) 141 flags |= PFR_FLAG_DUMMY; 142 143 bzero(&b, sizeof(b)); 144 bzero(&b2, sizeof(b2)); 145 bzero(&table, sizeof(table)); 146 if (tname != NULL) { 147 if (strlen(tname) >= PF_TABLE_NAME_SIZE) 148 usage(); 149 if (strlcpy(table.pfrt_name, tname, 150 sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name)) 151 errx(1, "pfctl_table: strlcpy"); 152 } 153 if (strlcpy(table.pfrt_anchor, anchor, 154 sizeof(table.pfrt_anchor)) >= sizeof(table.pfrt_anchor)) 155 errx(1, "pfctl_table: strlcpy"); 156 157 if (!strcmp(command, "-F")) { 158 if (argc || file != NULL) 159 usage(); 160 RVTEST(pfr_clr_tables(&table, &ndel, flags)); 161 xprintf(opts, "%d tables deleted", ndel); 162 } else if (!strcmp(command, "-s")) { 163 b.pfrb_type = (opts & PF_OPT_VERBOSE2) ? 164 PFRB_TSTATS : PFRB_TABLES; 165 if (argc || file != NULL) 166 usage(); 167 for (;;) { 168 pfr_buf_grow(&b, b.pfrb_size); 169 b.pfrb_size = b.pfrb_msize; 170 if (opts & PF_OPT_VERBOSE2) 171 RVTEST(pfr_get_tstats(&table, 172 b.pfrb_caddr, &b.pfrb_size, flags)); 173 else 174 RVTEST(pfr_get_tables(&table, 175 b.pfrb_caddr, &b.pfrb_size, flags)); 176 if (b.pfrb_size <= b.pfrb_msize) 177 break; 178 } 179
|
181 if (opts & PF_OPT_SHOWALL && b.pfrb_size > 0)
| 180 if ((opts & PF_OPT_SHOWALL) && b.pfrb_size > 0)
|
182 pfctl_print_title("TABLES:"); 183 184 PFRB_FOREACH(p, &b) 185 if (opts & PF_OPT_VERBOSE2) 186 print_tstats(p, opts & PF_OPT_DEBUG); 187 else 188 print_table(p, opts & PF_OPT_VERBOSE, 189 opts & PF_OPT_DEBUG); 190 } else if (!strcmp(command, "kill")) { 191 if (argc || file != NULL) 192 usage(); 193 RVTEST(pfr_del_tables(&table, 1, &ndel, flags)); 194 xprintf(opts, "%d table deleted", ndel); 195 } else if (!strcmp(command, "flush")) { 196 if (argc || file != NULL) 197 usage(); 198 RVTEST(pfr_clr_addrs(&table, &ndel, flags)); 199 xprintf(opts, "%d addresses deleted", ndel); 200 } else if (!strcmp(command, "add")) { 201 b.pfrb_type = PFRB_ADDRS; 202 if (load_addr(&b, argc, argv, file, 0)) 203 goto _error; 204 CREATE_TABLE; 205 if (opts & PF_OPT_VERBOSE) 206 flags |= PFR_FLAG_FEEDBACK; 207 RVTEST(pfr_add_addrs(&table, b.pfrb_caddr, b.pfrb_size, 208 &nadd, flags)); 209 xprintf(opts, "%d/%d addresses added", nadd, b.pfrb_size); 210 if (opts & PF_OPT_VERBOSE) 211 PFRB_FOREACH(a, &b) 212 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 213 print_addrx(a, NULL, 214 opts & PF_OPT_USEDNS); 215 } else if (!strcmp(command, "delete")) { 216 b.pfrb_type = PFRB_ADDRS; 217 if (load_addr(&b, argc, argv, file, 0)) 218 goto _error; 219 if (opts & PF_OPT_VERBOSE) 220 flags |= PFR_FLAG_FEEDBACK; 221 RVTEST(pfr_del_addrs(&table, b.pfrb_caddr, b.pfrb_size, 222 &ndel, flags)); 223 xprintf(opts, "%d/%d addresses deleted", ndel, b.pfrb_size); 224 if (opts & PF_OPT_VERBOSE) 225 PFRB_FOREACH(a, &b) 226 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 227 print_addrx(a, NULL, 228 opts & PF_OPT_USEDNS); 229 } else if (!strcmp(command, "replace")) { 230 b.pfrb_type = PFRB_ADDRS; 231 if (load_addr(&b, argc, argv, file, 0)) 232 goto _error; 233 CREATE_TABLE; 234 if (opts & PF_OPT_VERBOSE) 235 flags |= PFR_FLAG_FEEDBACK; 236 for (;;) { 237 int sz2 = b.pfrb_msize; 238 239 RVTEST(pfr_set_addrs(&table, b.pfrb_caddr, b.pfrb_size, 240 &sz2, &nadd, &ndel, &nchange, flags)); 241 if (sz2 <= b.pfrb_msize) { 242 b.pfrb_size = sz2; 243 break; 244 } else 245 pfr_buf_grow(&b, sz2); 246 } 247 if (nadd) 248 xprintf(opts, "%d addresses added", nadd); 249 if (ndel) 250 xprintf(opts, "%d addresses deleted", ndel); 251 if (nchange) 252 xprintf(opts, "%d addresses changed", nchange); 253 if (!nadd && !ndel && !nchange) 254 xprintf(opts, "no changes"); 255 if (opts & PF_OPT_VERBOSE) 256 PFRB_FOREACH(a, &b) 257 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 258 print_addrx(a, NULL, 259 opts & PF_OPT_USEDNS);
| 181 pfctl_print_title("TABLES:"); 182 183 PFRB_FOREACH(p, &b) 184 if (opts & PF_OPT_VERBOSE2) 185 print_tstats(p, opts & PF_OPT_DEBUG); 186 else 187 print_table(p, opts & PF_OPT_VERBOSE, 188 opts & PF_OPT_DEBUG); 189 } else if (!strcmp(command, "kill")) { 190 if (argc || file != NULL) 191 usage(); 192 RVTEST(pfr_del_tables(&table, 1, &ndel, flags)); 193 xprintf(opts, "%d table deleted", ndel); 194 } else if (!strcmp(command, "flush")) { 195 if (argc || file != NULL) 196 usage(); 197 RVTEST(pfr_clr_addrs(&table, &ndel, flags)); 198 xprintf(opts, "%d addresses deleted", ndel); 199 } else if (!strcmp(command, "add")) { 200 b.pfrb_type = PFRB_ADDRS; 201 if (load_addr(&b, argc, argv, file, 0)) 202 goto _error; 203 CREATE_TABLE; 204 if (opts & PF_OPT_VERBOSE) 205 flags |= PFR_FLAG_FEEDBACK; 206 RVTEST(pfr_add_addrs(&table, b.pfrb_caddr, b.pfrb_size, 207 &nadd, flags)); 208 xprintf(opts, "%d/%d addresses added", nadd, b.pfrb_size); 209 if (opts & PF_OPT_VERBOSE) 210 PFRB_FOREACH(a, &b) 211 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 212 print_addrx(a, NULL, 213 opts & PF_OPT_USEDNS); 214 } else if (!strcmp(command, "delete")) { 215 b.pfrb_type = PFRB_ADDRS; 216 if (load_addr(&b, argc, argv, file, 0)) 217 goto _error; 218 if (opts & PF_OPT_VERBOSE) 219 flags |= PFR_FLAG_FEEDBACK; 220 RVTEST(pfr_del_addrs(&table, b.pfrb_caddr, b.pfrb_size, 221 &ndel, flags)); 222 xprintf(opts, "%d/%d addresses deleted", ndel, b.pfrb_size); 223 if (opts & PF_OPT_VERBOSE) 224 PFRB_FOREACH(a, &b) 225 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 226 print_addrx(a, NULL, 227 opts & PF_OPT_USEDNS); 228 } else if (!strcmp(command, "replace")) { 229 b.pfrb_type = PFRB_ADDRS; 230 if (load_addr(&b, argc, argv, file, 0)) 231 goto _error; 232 CREATE_TABLE; 233 if (opts & PF_OPT_VERBOSE) 234 flags |= PFR_FLAG_FEEDBACK; 235 for (;;) { 236 int sz2 = b.pfrb_msize; 237 238 RVTEST(pfr_set_addrs(&table, b.pfrb_caddr, b.pfrb_size, 239 &sz2, &nadd, &ndel, &nchange, flags)); 240 if (sz2 <= b.pfrb_msize) { 241 b.pfrb_size = sz2; 242 break; 243 } else 244 pfr_buf_grow(&b, sz2); 245 } 246 if (nadd) 247 xprintf(opts, "%d addresses added", nadd); 248 if (ndel) 249 xprintf(opts, "%d addresses deleted", ndel); 250 if (nchange) 251 xprintf(opts, "%d addresses changed", nchange); 252 if (!nadd && !ndel && !nchange) 253 xprintf(opts, "no changes"); 254 if (opts & PF_OPT_VERBOSE) 255 PFRB_FOREACH(a, &b) 256 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 257 print_addrx(a, NULL, 258 opts & PF_OPT_USEDNS);
|
| 259 } else if (!strcmp(command, "expire")) { 260 const char *errstr; 261 u_int lifetime; 262 263 b.pfrb_type = PFRB_ASTATS; 264 b2.pfrb_type = PFRB_ADDRS; 265 if (argc != 1 || file != NULL) 266 usage(); 267 lifetime = strtonum(*argv, 0, UINT_MAX, &errstr); 268 if (errstr) 269 errx(1, "expiry time: %s", errstr); 270 for (;;) { 271 pfr_buf_grow(&b, b.pfrb_size); 272 b.pfrb_size = b.pfrb_msize; 273 RVTEST(pfr_get_astats(&table, b.pfrb_caddr, 274 &b.pfrb_size, flags)); 275 if (b.pfrb_size <= b.pfrb_msize) 276 break; 277 } 278 PFRB_FOREACH(p, &b) 279 if (time(NULL) - ((struct pfr_astats *)p)->pfras_tzero > 280 lifetime) 281 if (pfr_buf_add(&b2, 282 &((struct pfr_astats *)p)->pfras_a)) 283 err(1, "duplicate buffer"); 284 285 if (opts & PF_OPT_VERBOSE) 286 flags |= PFR_FLAG_FEEDBACK; 287 RVTEST(pfr_del_addrs(&table, b2.pfrb_caddr, b2.pfrb_size, 288 &ndel, flags)); 289 xprintf(opts, "%d/%d addresses expired", ndel, b2.pfrb_size); 290 if (opts & PF_OPT_VERBOSE) 291 PFRB_FOREACH(a, &b2) 292 if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) 293 print_addrx(a, NULL, 294 opts & PF_OPT_USEDNS);
|
260 } else if (!strcmp(command, "show")) { 261 b.pfrb_type = (opts & PF_OPT_VERBOSE) ? 262 PFRB_ASTATS : PFRB_ADDRS; 263 if (argc || file != NULL) 264 usage(); 265 for (;;) { 266 pfr_buf_grow(&b, b.pfrb_size); 267 b.pfrb_size = b.pfrb_msize; 268 if (opts & PF_OPT_VERBOSE) 269 RVTEST(pfr_get_astats(&table, b.pfrb_caddr, 270 &b.pfrb_size, flags)); 271 else 272 RVTEST(pfr_get_addrs(&table, b.pfrb_caddr, 273 &b.pfrb_size, flags)); 274 if (b.pfrb_size <= b.pfrb_msize) 275 break; 276 } 277 PFRB_FOREACH(p, &b) 278 if (opts & PF_OPT_VERBOSE) 279 print_astats(p, opts & PF_OPT_USEDNS); 280 else 281 print_addrx(p, NULL, opts & PF_OPT_USEDNS); 282 } else if (!strcmp(command, "test")) { 283 b.pfrb_type = PFRB_ADDRS; 284 b2.pfrb_type = PFRB_ADDRS; 285 286 if (load_addr(&b, argc, argv, file, 1)) 287 goto _error; 288 if (opts & PF_OPT_VERBOSE2) { 289 flags |= PFR_FLAG_REPLACE; 290 PFRB_FOREACH(a, &b) 291 if (pfr_buf_add(&b2, a)) 292 err(1, "duplicate buffer"); 293 } 294 RVTEST(pfr_tst_addrs(&table, b.pfrb_caddr, b.pfrb_size, 295 &nmatch, flags)); 296 xprintf(opts, "%d/%d addresses match", nmatch, b.pfrb_size);
| 295 } else if (!strcmp(command, "show")) { 296 b.pfrb_type = (opts & PF_OPT_VERBOSE) ? 297 PFRB_ASTATS : PFRB_ADDRS; 298 if (argc || file != NULL) 299 usage(); 300 for (;;) { 301 pfr_buf_grow(&b, b.pfrb_size); 302 b.pfrb_size = b.pfrb_msize; 303 if (opts & PF_OPT_VERBOSE) 304 RVTEST(pfr_get_astats(&table, b.pfrb_caddr, 305 &b.pfrb_size, flags)); 306 else 307 RVTEST(pfr_get_addrs(&table, b.pfrb_caddr, 308 &b.pfrb_size, flags)); 309 if (b.pfrb_size <= b.pfrb_msize) 310 break; 311 } 312 PFRB_FOREACH(p, &b) 313 if (opts & PF_OPT_VERBOSE) 314 print_astats(p, opts & PF_OPT_USEDNS); 315 else 316 print_addrx(p, NULL, opts & PF_OPT_USEDNS); 317 } else if (!strcmp(command, "test")) { 318 b.pfrb_type = PFRB_ADDRS; 319 b2.pfrb_type = PFRB_ADDRS; 320 321 if (load_addr(&b, argc, argv, file, 1)) 322 goto _error; 323 if (opts & PF_OPT_VERBOSE2) { 324 flags |= PFR_FLAG_REPLACE; 325 PFRB_FOREACH(a, &b) 326 if (pfr_buf_add(&b2, a)) 327 err(1, "duplicate buffer"); 328 } 329 RVTEST(pfr_tst_addrs(&table, b.pfrb_caddr, b.pfrb_size, 330 &nmatch, flags)); 331 xprintf(opts, "%d/%d addresses match", nmatch, b.pfrb_size);
|
297 if (opts & PF_OPT_VERBOSE && !(opts & PF_OPT_VERBOSE2))
| 332 if ((opts & PF_OPT_VERBOSE) && !(opts & PF_OPT_VERBOSE2))
|
298 PFRB_FOREACH(a, &b) 299 if (a->pfra_fback == PFR_FB_MATCH) 300 print_addrx(a, NULL, 301 opts & PF_OPT_USEDNS); 302 if (opts & PF_OPT_VERBOSE2) { 303 a2 = NULL; 304 PFRB_FOREACH(a, &b) { 305 a2 = pfr_buf_next(&b2, a2); 306 print_addrx(a2, a, opts & PF_OPT_USEDNS); 307 } 308 } 309 if (nmatch < b.pfrb_size) 310 rv = 2; 311 } else if (!strcmp(command, "zero")) { 312 if (argc || file != NULL) 313 usage(); 314 flags |= PFR_FLAG_ADDRSTOO; 315 RVTEST(pfr_clr_tstats(&table, 1, &nzero, flags)); 316 xprintf(opts, "%d table/stats cleared", nzero); 317 } else 318 warnx("pfctl_table: unknown command '%s'", command); 319 goto _cleanup; 320 321_error: 322 rv = -1; 323_cleanup: 324 pfr_buf_clear(&b); 325 pfr_buf_clear(&b2); 326 return (rv); 327} 328 329void 330print_table(struct pfr_table *ta, int verbose, int debug) 331{ 332 if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE)) 333 return; 334 if (verbose) { 335 printf("%c%c%c%c%c%c\t%s", 336 (ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-', 337 (ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-', 338 (ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-', 339 (ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-', 340 (ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-', 341 (ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-', 342 ta->pfrt_name); 343 if (ta->pfrt_anchor[0]) 344 printf("\t%s", ta->pfrt_anchor); 345 puts(""); 346 } else 347 puts(ta->pfrt_name); 348} 349 350void 351print_tstats(struct pfr_tstats *ts, int debug) 352{ 353 time_t time = ts->pfrts_tzero; 354 int dir, op; 355 356 if (!debug && !(ts->pfrts_flags & PFR_TFLAG_ACTIVE)) 357 return; 358 print_table(&ts->pfrts_t, 1, debug); 359 printf("\tAddresses: %d\n", ts->pfrts_cnt); 360 printf("\tCleared: %s", ctime(&time)); 361 printf("\tReferences: [ Anchors: %-18d Rules: %-18d ]\n", 362 ts->pfrts_refcnt[PFR_REFCNT_ANCHOR], 363 ts->pfrts_refcnt[PFR_REFCNT_RULE]); 364 printf("\tEvaluations: [ NoMatch: %-18llu Match: %-18llu ]\n", 365 (unsigned long long)ts->pfrts_nomatch, 366 (unsigned long long)ts->pfrts_match); 367 for (dir = 0; dir < PFR_DIR_MAX; dir++) 368 for (op = 0; op < PFR_OP_TABLE_MAX; op++) 369 printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", 370 stats_text[dir][op], 371 (unsigned long long)ts->pfrts_packets[dir][op], 372 (unsigned long long)ts->pfrts_bytes[dir][op]); 373} 374 375int 376load_addr(struct pfr_buffer *b, int argc, char *argv[], char *file, 377 int nonetwork) 378{ 379 while (argc--) 380 if (append_addr(b, *argv++, nonetwork)) { 381 if (errno) 382 warn("cannot decode %s", argv[-1]); 383 return (-1); 384 } 385 if (pfr_buf_load(b, file, nonetwork, append_addr)) { 386 warn("cannot load %s", file); 387 return (-1); 388 } 389 return (0); 390} 391 392void 393print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, int dns) 394{ 395 char ch, buf[256] = "{error}"; 396 char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y' }; 397 unsigned int fback, hostnet; 398 399 fback = (rad != NULL) ? rad->pfra_fback : ad->pfra_fback; 400 ch = (fback < sizeof(fb)/sizeof(*fb)) ? fb[fback] : '?'; 401 hostnet = (ad->pfra_af == AF_INET6) ? 128 : 32; 402 inet_ntop(ad->pfra_af, &ad->pfra_u, buf, sizeof(buf)); 403 printf("%c %c%s", ch, (ad->pfra_not?'!':' '), buf); 404 if (ad->pfra_net < hostnet) 405 printf("/%d", ad->pfra_net); 406 if (rad != NULL && fback != PFR_FB_NONE) { 407 if (strlcpy(buf, "{error}", sizeof(buf)) >= sizeof(buf)) 408 errx(1, "print_addrx: strlcpy"); 409 inet_ntop(rad->pfra_af, &rad->pfra_u, buf, sizeof(buf)); 410 printf("\t%c%s", (rad->pfra_not?'!':' '), buf); 411 if (rad->pfra_net < hostnet) 412 printf("/%d", rad->pfra_net); 413 } 414 if (rad != NULL && fback == PFR_FB_NONE) 415 printf("\t nomatch"); 416 if (dns && ad->pfra_net == hostnet) { 417 char host[NI_MAXHOST]; 418 union sockaddr_union sa; 419 420 strlcpy(host, "?", sizeof(host)); 421 bzero(&sa, sizeof(sa)); 422 sa.sa.sa_family = ad->pfra_af; 423 if (sa.sa.sa_family == AF_INET) { 424 sa.sa.sa_len = sizeof(sa.sin); 425 sa.sin.sin_addr = ad->pfra_ip4addr; 426 } else { 427 sa.sa.sa_len = sizeof(sa.sin6); 428 sa.sin6.sin6_addr = ad->pfra_ip6addr; 429 } 430 if (getnameinfo(&sa.sa, sa.sa.sa_len, host, sizeof(host), 431 NULL, 0, NI_NAMEREQD) == 0) 432 printf("\t(%s)", host); 433 } 434 printf("\n"); 435} 436 437void 438print_astats(struct pfr_astats *as, int dns) 439{ 440 time_t time = as->pfras_tzero; 441 int dir, op; 442 443 print_addrx(&as->pfras_a, NULL, dns); 444 printf("\tCleared: %s", ctime(&time)); 445 for (dir = 0; dir < PFR_DIR_MAX; dir++) 446 for (op = 0; op < PFR_OP_ADDR_MAX; op++) 447 printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", 448 stats_text[dir][op], 449 (unsigned long long)as->pfras_packets[dir][op], 450 (unsigned long long)as->pfras_bytes[dir][op]); 451} 452 453void 454radix_perror(void) 455{ 456 extern char *__progname; 457 fprintf(stderr, "%s: %s.\n", __progname, pfr_strerror(errno)); 458} 459 460int 461pfctl_define_table(char *name, int flags, int addrs, const char *anchor, 462 struct pfr_buffer *ab, u_int32_t ticket) 463{ 464 struct pfr_table tbl; 465 466 bzero(&tbl, sizeof(tbl)); 467 if (strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)) >= 468 sizeof(tbl.pfrt_name) || strlcpy(tbl.pfrt_anchor, anchor, 469 sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor)) 470 errx(1, "pfctl_define_table: strlcpy"); 471 tbl.pfrt_flags = flags; 472 473 return pfr_ina_define(&tbl, ab->pfrb_caddr, ab->pfrb_size, NULL, 474 NULL, ticket, addrs ? PFR_FLAG_ADDRSTOO : 0); 475} 476 477void 478warn_namespace_collision(const char *filter) 479{ 480 struct pfr_buffer b; 481 struct pfr_table *t; 482 const char *name = NULL, *lastcoll; 483 int coll = 0; 484 485 bzero(&b, sizeof(b)); 486 b.pfrb_type = PFRB_TABLES; 487 for (;;) { 488 pfr_buf_grow(&b, b.pfrb_size); 489 b.pfrb_size = b.pfrb_msize; 490 if (pfr_get_tables(NULL, b.pfrb_caddr, 491 &b.pfrb_size, PFR_FLAG_ALLRSETS)) 492 err(1, "pfr_get_tables"); 493 if (b.pfrb_size <= b.pfrb_msize) 494 break; 495 } 496 PFRB_FOREACH(t, &b) { 497 if (!(t->pfrt_flags & PFR_TFLAG_ACTIVE)) 498 continue; 499 if (filter != NULL && strcmp(filter, t->pfrt_name)) 500 continue; 501 if (!t->pfrt_anchor[0]) 502 name = t->pfrt_name; 503 else if (name != NULL && !strcmp(name, t->pfrt_name)) { 504 coll++; 505 lastcoll = name; 506 name = NULL; 507 } 508 } 509 if (coll == 1) 510 warnx("warning: namespace collision with <%s> global table.", 511 lastcoll); 512 else if (coll > 1) 513 warnx("warning: namespace collisions with %d global tables.", 514 coll); 515 pfr_buf_clear(&b); 516} 517 518void 519xprintf(int opts, const char *fmt, ...) 520{ 521 va_list args; 522 523 if (opts & PF_OPT_QUIET) 524 return; 525 526 va_start(args, fmt); 527 vfprintf(stderr, fmt, args); 528 va_end(args); 529 530 if (opts & PF_OPT_DUMMYACTION) 531 fprintf(stderr, " (dummy).\n"); 532 else if (opts & PF_OPT_NOACTION) 533 fprintf(stderr, " (syntax only).\n"); 534 else 535 fprintf(stderr, ".\n"); 536} 537 538 539/* interface stuff */ 540 541int 542pfctl_show_ifaces(const char *filter, int opts) 543{ 544 struct pfr_buffer b;
| 333 PFRB_FOREACH(a, &b) 334 if (a->pfra_fback == PFR_FB_MATCH) 335 print_addrx(a, NULL, 336 opts & PF_OPT_USEDNS); 337 if (opts & PF_OPT_VERBOSE2) { 338 a2 = NULL; 339 PFRB_FOREACH(a, &b) { 340 a2 = pfr_buf_next(&b2, a2); 341 print_addrx(a2, a, opts & PF_OPT_USEDNS); 342 } 343 } 344 if (nmatch < b.pfrb_size) 345 rv = 2; 346 } else if (!strcmp(command, "zero")) { 347 if (argc || file != NULL) 348 usage(); 349 flags |= PFR_FLAG_ADDRSTOO; 350 RVTEST(pfr_clr_tstats(&table, 1, &nzero, flags)); 351 xprintf(opts, "%d table/stats cleared", nzero); 352 } else 353 warnx("pfctl_table: unknown command '%s'", command); 354 goto _cleanup; 355 356_error: 357 rv = -1; 358_cleanup: 359 pfr_buf_clear(&b); 360 pfr_buf_clear(&b2); 361 return (rv); 362} 363 364void 365print_table(struct pfr_table *ta, int verbose, int debug) 366{ 367 if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE)) 368 return; 369 if (verbose) { 370 printf("%c%c%c%c%c%c\t%s", 371 (ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-', 372 (ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-', 373 (ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-', 374 (ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-', 375 (ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-', 376 (ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-', 377 ta->pfrt_name); 378 if (ta->pfrt_anchor[0]) 379 printf("\t%s", ta->pfrt_anchor); 380 puts(""); 381 } else 382 puts(ta->pfrt_name); 383} 384 385void 386print_tstats(struct pfr_tstats *ts, int debug) 387{ 388 time_t time = ts->pfrts_tzero; 389 int dir, op; 390 391 if (!debug && !(ts->pfrts_flags & PFR_TFLAG_ACTIVE)) 392 return; 393 print_table(&ts->pfrts_t, 1, debug); 394 printf("\tAddresses: %d\n", ts->pfrts_cnt); 395 printf("\tCleared: %s", ctime(&time)); 396 printf("\tReferences: [ Anchors: %-18d Rules: %-18d ]\n", 397 ts->pfrts_refcnt[PFR_REFCNT_ANCHOR], 398 ts->pfrts_refcnt[PFR_REFCNT_RULE]); 399 printf("\tEvaluations: [ NoMatch: %-18llu Match: %-18llu ]\n", 400 (unsigned long long)ts->pfrts_nomatch, 401 (unsigned long long)ts->pfrts_match); 402 for (dir = 0; dir < PFR_DIR_MAX; dir++) 403 for (op = 0; op < PFR_OP_TABLE_MAX; op++) 404 printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", 405 stats_text[dir][op], 406 (unsigned long long)ts->pfrts_packets[dir][op], 407 (unsigned long long)ts->pfrts_bytes[dir][op]); 408} 409 410int 411load_addr(struct pfr_buffer *b, int argc, char *argv[], char *file, 412 int nonetwork) 413{ 414 while (argc--) 415 if (append_addr(b, *argv++, nonetwork)) { 416 if (errno) 417 warn("cannot decode %s", argv[-1]); 418 return (-1); 419 } 420 if (pfr_buf_load(b, file, nonetwork, append_addr)) { 421 warn("cannot load %s", file); 422 return (-1); 423 } 424 return (0); 425} 426 427void 428print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, int dns) 429{ 430 char ch, buf[256] = "{error}"; 431 char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y' }; 432 unsigned int fback, hostnet; 433 434 fback = (rad != NULL) ? rad->pfra_fback : ad->pfra_fback; 435 ch = (fback < sizeof(fb)/sizeof(*fb)) ? fb[fback] : '?'; 436 hostnet = (ad->pfra_af == AF_INET6) ? 128 : 32; 437 inet_ntop(ad->pfra_af, &ad->pfra_u, buf, sizeof(buf)); 438 printf("%c %c%s", ch, (ad->pfra_not?'!':' '), buf); 439 if (ad->pfra_net < hostnet) 440 printf("/%d", ad->pfra_net); 441 if (rad != NULL && fback != PFR_FB_NONE) { 442 if (strlcpy(buf, "{error}", sizeof(buf)) >= sizeof(buf)) 443 errx(1, "print_addrx: strlcpy"); 444 inet_ntop(rad->pfra_af, &rad->pfra_u, buf, sizeof(buf)); 445 printf("\t%c%s", (rad->pfra_not?'!':' '), buf); 446 if (rad->pfra_net < hostnet) 447 printf("/%d", rad->pfra_net); 448 } 449 if (rad != NULL && fback == PFR_FB_NONE) 450 printf("\t nomatch"); 451 if (dns && ad->pfra_net == hostnet) { 452 char host[NI_MAXHOST]; 453 union sockaddr_union sa; 454 455 strlcpy(host, "?", sizeof(host)); 456 bzero(&sa, sizeof(sa)); 457 sa.sa.sa_family = ad->pfra_af; 458 if (sa.sa.sa_family == AF_INET) { 459 sa.sa.sa_len = sizeof(sa.sin); 460 sa.sin.sin_addr = ad->pfra_ip4addr; 461 } else { 462 sa.sa.sa_len = sizeof(sa.sin6); 463 sa.sin6.sin6_addr = ad->pfra_ip6addr; 464 } 465 if (getnameinfo(&sa.sa, sa.sa.sa_len, host, sizeof(host), 466 NULL, 0, NI_NAMEREQD) == 0) 467 printf("\t(%s)", host); 468 } 469 printf("\n"); 470} 471 472void 473print_astats(struct pfr_astats *as, int dns) 474{ 475 time_t time = as->pfras_tzero; 476 int dir, op; 477 478 print_addrx(&as->pfras_a, NULL, dns); 479 printf("\tCleared: %s", ctime(&time)); 480 for (dir = 0; dir < PFR_DIR_MAX; dir++) 481 for (op = 0; op < PFR_OP_ADDR_MAX; op++) 482 printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", 483 stats_text[dir][op], 484 (unsigned long long)as->pfras_packets[dir][op], 485 (unsigned long long)as->pfras_bytes[dir][op]); 486} 487 488void 489radix_perror(void) 490{ 491 extern char *__progname; 492 fprintf(stderr, "%s: %s.\n", __progname, pfr_strerror(errno)); 493} 494 495int 496pfctl_define_table(char *name, int flags, int addrs, const char *anchor, 497 struct pfr_buffer *ab, u_int32_t ticket) 498{ 499 struct pfr_table tbl; 500 501 bzero(&tbl, sizeof(tbl)); 502 if (strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)) >= 503 sizeof(tbl.pfrt_name) || strlcpy(tbl.pfrt_anchor, anchor, 504 sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor)) 505 errx(1, "pfctl_define_table: strlcpy"); 506 tbl.pfrt_flags = flags; 507 508 return pfr_ina_define(&tbl, ab->pfrb_caddr, ab->pfrb_size, NULL, 509 NULL, ticket, addrs ? PFR_FLAG_ADDRSTOO : 0); 510} 511 512void 513warn_namespace_collision(const char *filter) 514{ 515 struct pfr_buffer b; 516 struct pfr_table *t; 517 const char *name = NULL, *lastcoll; 518 int coll = 0; 519 520 bzero(&b, sizeof(b)); 521 b.pfrb_type = PFRB_TABLES; 522 for (;;) { 523 pfr_buf_grow(&b, b.pfrb_size); 524 b.pfrb_size = b.pfrb_msize; 525 if (pfr_get_tables(NULL, b.pfrb_caddr, 526 &b.pfrb_size, PFR_FLAG_ALLRSETS)) 527 err(1, "pfr_get_tables"); 528 if (b.pfrb_size <= b.pfrb_msize) 529 break; 530 } 531 PFRB_FOREACH(t, &b) { 532 if (!(t->pfrt_flags & PFR_TFLAG_ACTIVE)) 533 continue; 534 if (filter != NULL && strcmp(filter, t->pfrt_name)) 535 continue; 536 if (!t->pfrt_anchor[0]) 537 name = t->pfrt_name; 538 else if (name != NULL && !strcmp(name, t->pfrt_name)) { 539 coll++; 540 lastcoll = name; 541 name = NULL; 542 } 543 } 544 if (coll == 1) 545 warnx("warning: namespace collision with <%s> global table.", 546 lastcoll); 547 else if (coll > 1) 548 warnx("warning: namespace collisions with %d global tables.", 549 coll); 550 pfr_buf_clear(&b); 551} 552 553void 554xprintf(int opts, const char *fmt, ...) 555{ 556 va_list args; 557 558 if (opts & PF_OPT_QUIET) 559 return; 560 561 va_start(args, fmt); 562 vfprintf(stderr, fmt, args); 563 va_end(args); 564 565 if (opts & PF_OPT_DUMMYACTION) 566 fprintf(stderr, " (dummy).\n"); 567 else if (opts & PF_OPT_NOACTION) 568 fprintf(stderr, " (syntax only).\n"); 569 else 570 fprintf(stderr, ".\n"); 571} 572 573 574/* interface stuff */ 575 576int 577pfctl_show_ifaces(const char *filter, int opts) 578{ 579 struct pfr_buffer b;
|
545 struct pfi_if *p; 546 int i = 0, f = PFI_FLAG_GROUP|PFI_FLAG_INSTANCE;
| 580 struct pfi_kif *p; 581 int i = 0;
|
547
| 582
|
548 if (filter != NULL && *filter && !isdigit(filter[strlen(filter)-1])) 549 f &= ~PFI_FLAG_INSTANCE;
| |
550 bzero(&b, sizeof(b)); 551 b.pfrb_type = PFRB_IFACES; 552 for (;;) { 553 pfr_buf_grow(&b, b.pfrb_size); 554 b.pfrb_size = b.pfrb_msize;
| 583 bzero(&b, sizeof(b)); 584 b.pfrb_type = PFRB_IFACES; 585 for (;;) { 586 pfr_buf_grow(&b, b.pfrb_size); 587 b.pfrb_size = b.pfrb_msize;
|
555 if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size, f)) {
| 588 if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size)) {
|
556 radix_perror(); 557 return (1); 558 } 559 if (b.pfrb_size <= b.pfrb_msize) 560 break; 561 i++; 562 } 563 if (opts & PF_OPT_SHOWALL) 564 pfctl_print_title("INTERFACES:"); 565 PFRB_FOREACH(p, &b) 566 print_iface(p, opts); 567 return (0); 568} 569 570void
| 589 radix_perror(); 590 return (1); 591 } 592 if (b.pfrb_size <= b.pfrb_msize) 593 break; 594 i++; 595 } 596 if (opts & PF_OPT_SHOWALL) 597 pfctl_print_title("INTERFACES:"); 598 PFRB_FOREACH(p, &b) 599 print_iface(p, opts); 600 return (0); 601} 602 603void
|
571print_iface(struct pfi_if *p, int opts)
| 604print_iface(struct pfi_kif *p, int opts)
|
572{
| 605{
|
573 time_t tzero = p->pfif_tzero; 574 int flags = (opts & PF_OPT_VERBOSE) ? p->pfif_flags : 0; 575 int first = 1;
| 606 time_t tzero = p->pfik_tzero;
|
576 int i, af, dir, act; 577
| 607 int i, af, dir, act; 608
|
578 printf("%s", p->pfif_name); 579 oprintf(flags, PFI_IFLAG_INSTANCE, "instance", &first, 0); 580 oprintf(flags, PFI_IFLAG_GROUP, "group", &first, 0); 581 oprintf(flags, PFI_IFLAG_CLONABLE, "clonable", &first, 0); 582 oprintf(flags, PFI_IFLAG_DYNAMIC, "dynamic", &first, 0); 583 oprintf(flags, PFI_IFLAG_ATTACHED, "attached", &first, 0); 584 oprintf(flags, PFI_IFLAG_SKIP, "skipped", &first, 1); 585#ifdef __FreeBSD__ 586 first = 1; 587 oprintf(flags, PFI_IFLAG_PLACEHOLDER, "placeholder", &first, 1); 588#endif
| 609 printf("%s", p->pfik_name); 610 if (opts & PF_OPT_VERBOSE) { 611 if (p->pfik_flags & PFI_IFLAG_SKIP) 612 printf(" (skip)"); 613 }
|
589 printf("\n"); 590 591 if (!(opts & PF_OPT_VERBOSE2)) 592 return; 593 printf("\tCleared: %s", ctime(&tzero)); 594 printf("\tReferences: [ States: %-18d Rules: %-18d ]\n",
| 614 printf("\n"); 615 616 if (!(opts & PF_OPT_VERBOSE2)) 617 return; 618 printf("\tCleared: %s", ctime(&tzero)); 619 printf("\tReferences: [ States: %-18d Rules: %-18d ]\n",
|
595 p->pfif_states, p->pfif_rules);
| 620 p->pfik_states, p->pfik_rules);
|
596 for (i = 0; i < 8; i++) { 597 af = (i>>2) & 1; 598 dir = (i>>1) &1; 599 act = i & 1; 600 printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", 601 istats_text[af][dir][act],
| 621 for (i = 0; i < 8; i++) { 622 af = (i>>2) & 1; 623 dir = (i>>1) &1; 624 act = i & 1; 625 printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n", 626 istats_text[af][dir][act],
|
602 (unsigned long long)p->pfif_packets[af][dir][act], 603 (unsigned long long)p->pfif_bytes[af][dir][act]);
| 627 (unsigned long long)p->pfik_packets[af][dir][act], 628 (unsigned long long)p->pfik_bytes[af][dir][act]);
|
604 } 605}
| 629 } 630}
|
606 607void 608oprintf(int flags, int flag, const char *s, int *first, int last) 609{ 610 if (flags & flag) { 611 printf(*first ? "\t(%s" : ", %s", s); 612 *first = 0; 613 } 614 if (last && !*first) 615 printf(")"); 616} 617
| |
| |