Wed Apr 22 23:40:40 2020 UTC ()
Externalize variables owned logically by pf_ruleset.c


(joerg)
diff -r1.5 -r1.6 src/dist/pf/sbin/pfctl/pfctl.c

cvs diff -r1.5 -r1.6 src/dist/pf/sbin/pfctl/pfctl.c (switch to unified diff)

--- src/dist/pf/sbin/pfctl/pfctl.c 2008/06/18 09:06:26 1.5
+++ src/dist/pf/sbin/pfctl/pfctl.c 2020/04/22 23:40:40 1.6
@@ -1,1099 +1,1099 @@ @@ -1,1099 +1,1099 @@
1/* $NetBSD: pfctl.c,v 1.5 2008/06/18 09:06:26 yamt Exp $ */ 1/* $NetBSD: pfctl.c,v 1.6 2020/04/22 23:40:40 joerg Exp $ */
2/* $OpenBSD: pfctl.c,v 1.268 2007/06/30 18:25:08 henning Exp $ */ 2/* $OpenBSD: pfctl.c,v 1.268 2007/06/30 18:25:08 henning Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2001 Daniel Hartmeier
6 * Copyright (c) 2002,2003 Henning Brauer 6 * Copyright (c) 2002,2003 Henning Brauer
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 12 *
13 * - Redistributions of source code must retain the above copyright 13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above 15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following 16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided 17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution. 18 * with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 * 32 *
33 */ 33 */
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/ioctl.h> 36#include <sys/ioctl.h>
37#include <sys/socket.h> 37#include <sys/socket.h>
38#include <sys/stat.h> 38#include <sys/stat.h>
39 39
40#include <net/if.h> 40#include <net/if.h>
41#include <netinet/in.h> 41#include <netinet/in.h>
42#include <net/pfvar.h> 42#include <net/pfvar.h>
43#include <arpa/inet.h> 43#include <arpa/inet.h>
44#include <altq/altq.h> 44#include <altq/altq.h>
45#include <sys/sysctl.h> 45#include <sys/sysctl.h>
46 46
47#include <err.h> 47#include <err.h>
48#include <errno.h> 48#include <errno.h>
49#include <fcntl.h> 49#include <fcntl.h>
50#include <limits.h> 50#include <limits.h>
51#include <netdb.h> 51#include <netdb.h>
52#include <stdio.h> 52#include <stdio.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <string.h> 54#include <string.h>
55#include <unistd.h> 55#include <unistd.h>
56 56
57#include "pfctl_parser.h" 57#include "pfctl_parser.h"
58#include "pfctl.h" 58#include "pfctl.h"
59 59
60void usage(void); 60void usage(void);
61int pfctl_enable(int, int); 61int pfctl_enable(int, int);
62int pfctl_disable(int, int); 62int pfctl_disable(int, int);
63int pfctl_clear_stats(int, int); 63int pfctl_clear_stats(int, int);
64int pfctl_clear_interface_flags(int, int); 64int pfctl_clear_interface_flags(int, int);
65int pfctl_clear_rules(int, int, char *); 65int pfctl_clear_rules(int, int, char *);
66int pfctl_clear_nat(int, int, char *); 66int pfctl_clear_nat(int, int, char *);
67int pfctl_clear_altq(int, int); 67int pfctl_clear_altq(int, int);
68int pfctl_clear_src_nodes(int, int); 68int pfctl_clear_src_nodes(int, int);
69int pfctl_clear_states(int, const char *, int); 69int pfctl_clear_states(int, const char *, int);
70void pfctl_addrprefix(char *, struct pf_addr *); 70void pfctl_addrprefix(char *, struct pf_addr *);
71int pfctl_kill_src_nodes(int, const char *, int); 71int pfctl_kill_src_nodes(int, const char *, int);
72int pfctl_kill_states(int, const char *, int); 72int pfctl_kill_states(int, const char *, int);
73void pfctl_init_options(struct pfctl *); 73void pfctl_init_options(struct pfctl *);
74int pfctl_load_options(struct pfctl *); 74int pfctl_load_options(struct pfctl *);
75int pfctl_load_limit(struct pfctl *, unsigned int, unsigned int); 75int pfctl_load_limit(struct pfctl *, unsigned int, unsigned int);
76int pfctl_load_timeout(struct pfctl *, unsigned int, unsigned int); 76int pfctl_load_timeout(struct pfctl *, unsigned int, unsigned int);
77int pfctl_load_debug(struct pfctl *, unsigned int); 77int pfctl_load_debug(struct pfctl *, unsigned int);
78int pfctl_load_logif(struct pfctl *, char *); 78int pfctl_load_logif(struct pfctl *, char *);
79int pfctl_load_hostid(struct pfctl *, unsigned int); 79int pfctl_load_hostid(struct pfctl *, unsigned int);
80int pfctl_get_pool(int, struct pf_pool *, u_int32_t, u_int32_t, int, 80int pfctl_get_pool(int, struct pf_pool *, u_int32_t, u_int32_t, int,
81 char *); 81 char *);
82void pfctl_print_rule_counters(struct pf_rule *, int); 82void pfctl_print_rule_counters(struct pf_rule *, int);
83int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int); 83int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int);
84int pfctl_show_nat(int, int, char *); 84int pfctl_show_nat(int, int, char *);
85int pfctl_show_src_nodes(int, int); 85int pfctl_show_src_nodes(int, int);
86int pfctl_show_states(int, const char *, int); 86int pfctl_show_states(int, const char *, int);
87int pfctl_show_status(int, int); 87int pfctl_show_status(int, int);
88int pfctl_show_timeouts(int, int); 88int pfctl_show_timeouts(int, int);
89int pfctl_show_limits(int, int); 89int pfctl_show_limits(int, int);
90void pfctl_debug(int, u_int32_t, int); 90void pfctl_debug(int, u_int32_t, int);
91int pfctl_test_altqsupport(int, int); 91int pfctl_test_altqsupport(int, int);
92int pfctl_show_anchors(int, int, char *); 92int pfctl_show_anchors(int, int, char *);
93int pfctl_ruleset_trans(struct pfctl *, char *, struct pf_anchor *); 93int pfctl_ruleset_trans(struct pfctl *, char *, struct pf_anchor *);
94int pfctl_load_ruleset(struct pfctl *, char *, 94int pfctl_load_ruleset(struct pfctl *, char *,
95 struct pf_ruleset *, int, int); 95 struct pf_ruleset *, int, int);
96int pfctl_load_rule(struct pfctl *, char *, struct pf_rule *, int); 96int pfctl_load_rule(struct pfctl *, char *, struct pf_rule *, int);
97const char *pfctl_lookup_option(char *, const char **); 97const char *pfctl_lookup_option(char *, const char **);
98 98
99struct pf_anchor_global pf_anchors; 99extern struct pf_anchor_global pf_anchors;
100struct pf_anchor pf_main_anchor; 100extern struct pf_anchor pf_main_anchor;
101 101
102const char *clearopt; 102const char *clearopt;
103char *rulesopt; 103char *rulesopt;
104const char *showopt; 104const char *showopt;
105const char *debugopt; 105const char *debugopt;
106char *anchoropt; 106char *anchoropt;
107const char *optiopt = NULL; 107const char *optiopt = NULL;
108char *pf_device = "/dev/pf"; 108char *pf_device = "/dev/pf";
109char *ifaceopt; 109char *ifaceopt;
110char *tableopt; 110char *tableopt;
111const char *tblcmdopt; 111const char *tblcmdopt;
112int src_node_killers; 112int src_node_killers;
113char *src_node_kill[2]; 113char *src_node_kill[2];
114int state_killers; 114int state_killers;
115char *state_kill[2]; 115char *state_kill[2];
116int loadopt; 116int loadopt;
117int altqsupport; 117int altqsupport;
118 118
119int dev = -1; 119int dev = -1;
120int first_title = 1; 120int first_title = 1;
121int labels = 0; 121int labels = 0;
122 122
123const char *infile; 123const char *infile;
124 124
125#define INDENT(d, o) do { \ 125#define INDENT(d, o) do { \
126 if (o) { \ 126 if (o) { \
127 int i; \ 127 int i; \
128 for (i=0; i < d; i++) \ 128 for (i=0; i < d; i++) \
129 printf(" "); \ 129 printf(" "); \
130 } \ 130 } \
131 } while (0); \ 131 } while (0); \
132 132
133 133
134static const struct { 134static const struct {
135 const char *name; 135 const char *name;
136 int index; 136 int index;
137} pf_limits[] = { 137} pf_limits[] = {
138 { "states", PF_LIMIT_STATES }, 138 { "states", PF_LIMIT_STATES },
139 { "src-nodes", PF_LIMIT_SRC_NODES }, 139 { "src-nodes", PF_LIMIT_SRC_NODES },
140 { "frags", PF_LIMIT_FRAGS }, 140 { "frags", PF_LIMIT_FRAGS },
141 { "tables", PF_LIMIT_TABLES }, 141 { "tables", PF_LIMIT_TABLES },
142 { "table-entries", PF_LIMIT_TABLE_ENTRIES }, 142 { "table-entries", PF_LIMIT_TABLE_ENTRIES },
143 { NULL, 0 } 143 { NULL, 0 }
144}; 144};
145 145
146struct pf_hint { 146struct pf_hint {
147 const char *name; 147 const char *name;
148 int timeout; 148 int timeout;
149}; 149};
150static const struct pf_hint pf_hint_normal[] = { 150static const struct pf_hint pf_hint_normal[] = {
151 { "tcp.first", 2 * 60 }, 151 { "tcp.first", 2 * 60 },
152 { "tcp.opening", 30 }, 152 { "tcp.opening", 30 },
153 { "tcp.established", 24 * 60 * 60 }, 153 { "tcp.established", 24 * 60 * 60 },
154 { "tcp.closing", 15 * 60 }, 154 { "tcp.closing", 15 * 60 },
155 { "tcp.finwait", 45 }, 155 { "tcp.finwait", 45 },
156 { "tcp.closed", 90 }, 156 { "tcp.closed", 90 },
157 { "tcp.tsdiff", 30 }, 157 { "tcp.tsdiff", 30 },
158 { NULL, 0 } 158 { NULL, 0 }
159}; 159};
160static const struct pf_hint pf_hint_satellite[] = { 160static const struct pf_hint pf_hint_satellite[] = {
161 { "tcp.first", 3 * 60 }, 161 { "tcp.first", 3 * 60 },
162 { "tcp.opening", 30 + 5 }, 162 { "tcp.opening", 30 + 5 },
163 { "tcp.established", 24 * 60 * 60 }, 163 { "tcp.established", 24 * 60 * 60 },
164 { "tcp.closing", 15 * 60 + 5 }, 164 { "tcp.closing", 15 * 60 + 5 },
165 { "tcp.finwait", 45 + 5 }, 165 { "tcp.finwait", 45 + 5 },
166 { "tcp.closed", 90 + 5 }, 166 { "tcp.closed", 90 + 5 },
167 { "tcp.tsdiff", 60 }, 167 { "tcp.tsdiff", 60 },
168 { NULL, 0 } 168 { NULL, 0 }
169}; 169};
170static const struct pf_hint pf_hint_conservative[] = { 170static const struct pf_hint pf_hint_conservative[] = {
171 { "tcp.first", 60 * 60 }, 171 { "tcp.first", 60 * 60 },
172 { "tcp.opening", 15 * 60 }, 172 { "tcp.opening", 15 * 60 },
173 { "tcp.established", 5 * 24 * 60 * 60 }, 173 { "tcp.established", 5 * 24 * 60 * 60 },
174 { "tcp.closing", 60 * 60 }, 174 { "tcp.closing", 60 * 60 },
175 { "tcp.finwait", 10 * 60 }, 175 { "tcp.finwait", 10 * 60 },
176 { "tcp.closed", 3 * 60 }, 176 { "tcp.closed", 3 * 60 },
177 { "tcp.tsdiff", 60 }, 177 { "tcp.tsdiff", 60 },
178 { NULL, 0 } 178 { NULL, 0 }
179}; 179};
180static const struct pf_hint pf_hint_aggressive[] = { 180static const struct pf_hint pf_hint_aggressive[] = {
181 { "tcp.first", 30 }, 181 { "tcp.first", 30 },
182 { "tcp.opening", 5 }, 182 { "tcp.opening", 5 },
183 { "tcp.established", 5 * 60 * 60 }, 183 { "tcp.established", 5 * 60 * 60 },
184 { "tcp.closing", 60 }, 184 { "tcp.closing", 60 },
185 { "tcp.finwait", 30 }, 185 { "tcp.finwait", 30 },
186 { "tcp.closed", 30 }, 186 { "tcp.closed", 30 },
187 { "tcp.tsdiff", 10 }, 187 { "tcp.tsdiff", 10 },
188 { NULL, 0 } 188 { NULL, 0 }
189}; 189};
190 190
191static const struct { 191static const struct {
192 const char *name; 192 const char *name;
193 const struct pf_hint *hint; 193 const struct pf_hint *hint;
194} pf_hints[] = { 194} pf_hints[] = {
195 { "normal", pf_hint_normal }, 195 { "normal", pf_hint_normal },
196 { "satellite", pf_hint_satellite }, 196 { "satellite", pf_hint_satellite },
197 { "high-latency", pf_hint_satellite }, 197 { "high-latency", pf_hint_satellite },
198 { "conservative", pf_hint_conservative }, 198 { "conservative", pf_hint_conservative },
199 { "aggressive", pf_hint_aggressive }, 199 { "aggressive", pf_hint_aggressive },
200 { NULL, NULL } 200 { NULL, NULL }
201}; 201};
202 202
203static const char *clearopt_list[] = { 203static const char *clearopt_list[] = {
204 "nat", "queue", "rules", "Sources", 204 "nat", "queue", "rules", "Sources",
205 "states", "info", "Tables", "osfp", "all", NULL 205 "states", "info", "Tables", "osfp", "all", NULL
206}; 206};
207 207
208static const char *showopt_list[] = { 208static const char *showopt_list[] = {
209 "nat", "queue", "rules", "Anchors", "Sources", "states", "info", 209 "nat", "queue", "rules", "Anchors", "Sources", "states", "info",
210 "Interfaces", "labels", "timeouts", "memory", "Tables", "osfp", 210 "Interfaces", "labels", "timeouts", "memory", "Tables", "osfp",
211 "all", NULL 211 "all", NULL
212}; 212};
213 213
214static const char *tblcmdopt_list[] = { 214static const char *tblcmdopt_list[] = {
215 "kill", "flush", "add", "delete", "load", "replace", "show", 215 "kill", "flush", "add", "delete", "load", "replace", "show",
216 "test", "zero", "expire", NULL 216 "test", "zero", "expire", NULL
217}; 217};
218 218
219static const char *debugopt_list[] = { 219static const char *debugopt_list[] = {
220 "none", "urgent", "misc", "loud", NULL 220 "none", "urgent", "misc", "loud", NULL
221}; 221};
222 222
223static const char *optiopt_list[] = { 223static const char *optiopt_list[] = {
224 "none", "basic", "profile", NULL 224 "none", "basic", "profile", NULL
225}; 225};
226 226
227void 227void
228usage(void) 228usage(void)
229{ 229{
230 extern char *__progname; 230 extern char *__progname;
231 231
232 fprintf(stderr, "usage: %s [-AdeghmNnOqRrvz] ", __progname); 232 fprintf(stderr, "usage: %s [-AdeghmNnOqRrvz] ", __progname);
233 fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n"); 233 fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n");
234 fprintf(stderr, "\t[-f file] [-i interface] [-K host | network] "); 234 fprintf(stderr, "\t[-f file] [-i interface] [-K host | network] ");
235 fprintf(stderr, "[-k host | network]\n"); 235 fprintf(stderr, "[-k host | network]\n");
236 fprintf(stderr, "\t[-o level] [-p device] [-s modifier]\n"); 236 fprintf(stderr, "\t[-o level] [-p device] [-s modifier]\n");
237 fprintf(stderr, "\t[-t table -T command [address ...]] [-x level]\n"); 237 fprintf(stderr, "\t[-t table -T command [address ...]] [-x level]\n");
238 exit(1); 238 exit(1);
239} 239}
240 240
241int 241int
242pfctl_enable(int dev, int opts) 242pfctl_enable(int dev, int opts)
243{ 243{
244 if (ioctl(dev, DIOCSTART)) { 244 if (ioctl(dev, DIOCSTART)) {
245 if (errno == EEXIST) 245 if (errno == EEXIST)
246 errx(1, "pf already enabled"); 246 errx(1, "pf already enabled");
247 else 247 else
248 err(1, "DIOCSTART"); 248 err(1, "DIOCSTART");
249 } 249 }
250 if ((opts & PF_OPT_QUIET) == 0) 250 if ((opts & PF_OPT_QUIET) == 0)
251 fprintf(stderr, "pf enabled\n"); 251 fprintf(stderr, "pf enabled\n");
252 252
253 if (altqsupport && ioctl(dev, DIOCSTARTALTQ)) 253 if (altqsupport && ioctl(dev, DIOCSTARTALTQ))
254 if (errno != EEXIST) 254 if (errno != EEXIST)
255 err(1, "DIOCSTARTALTQ"); 255 err(1, "DIOCSTARTALTQ");
256 256
257 return (0); 257 return (0);
258} 258}
259 259
260int 260int
261pfctl_disable(int dev, int opts) 261pfctl_disable(int dev, int opts)
262{ 262{
263 if (ioctl(dev, DIOCSTOP)) { 263 if (ioctl(dev, DIOCSTOP)) {
264 if (errno == ENOENT) 264 if (errno == ENOENT)
265 errx(1, "pf not enabled"); 265 errx(1, "pf not enabled");
266 else 266 else
267 err(1, "DIOCSTOP"); 267 err(1, "DIOCSTOP");
268 } 268 }
269 if ((opts & PF_OPT_QUIET) == 0) 269 if ((opts & PF_OPT_QUIET) == 0)
270 fprintf(stderr, "pf disabled\n"); 270 fprintf(stderr, "pf disabled\n");
271 271
272 if (altqsupport && ioctl(dev, DIOCSTOPALTQ)) 272 if (altqsupport && ioctl(dev, DIOCSTOPALTQ))
273 if (errno != ENOENT) 273 if (errno != ENOENT)
274 err(1, "DIOCSTOPALTQ"); 274 err(1, "DIOCSTOPALTQ");
275 275
276 return (0); 276 return (0);
277} 277}
278 278
279int 279int
280pfctl_clear_stats(int dev, int opts) 280pfctl_clear_stats(int dev, int opts)
281{ 281{
282 if (ioctl(dev, DIOCCLRSTATUS)) 282 if (ioctl(dev, DIOCCLRSTATUS))
283 err(1, "DIOCCLRSTATUS"); 283 err(1, "DIOCCLRSTATUS");
284 if ((opts & PF_OPT_QUIET) == 0) 284 if ((opts & PF_OPT_QUIET) == 0)
285 fprintf(stderr, "pf: statistics cleared\n"); 285 fprintf(stderr, "pf: statistics cleared\n");
286 return (0); 286 return (0);
287} 287}
288 288
289int 289int
290pfctl_clear_interface_flags(int dev, int opts) 290pfctl_clear_interface_flags(int dev, int opts)
291{ 291{
292 struct pfioc_iface pi; 292 struct pfioc_iface pi;
293 293
294 if ((opts & PF_OPT_NOACTION) == 0) { 294 if ((opts & PF_OPT_NOACTION) == 0) {
295 bzero(&pi, sizeof(pi)); 295 bzero(&pi, sizeof(pi));
296 pi.pfiio_flags = PFI_IFLAG_SKIP; 296 pi.pfiio_flags = PFI_IFLAG_SKIP;
297 297
298 if (ioctl(dev, DIOCCLRIFFLAG, &pi)) 298 if (ioctl(dev, DIOCCLRIFFLAG, &pi))
299 err(1, "DIOCCLRIFFLAG"); 299 err(1, "DIOCCLRIFFLAG");
300 if ((opts & PF_OPT_QUIET) == 0) 300 if ((opts & PF_OPT_QUIET) == 0)
301 fprintf(stderr, "pf: interface flags reset\n"); 301 fprintf(stderr, "pf: interface flags reset\n");
302 } 302 }
303 return (0); 303 return (0);
304} 304}
305 305
306int 306int
307pfctl_clear_rules(int dev, int opts, char *anchorname) 307pfctl_clear_rules(int dev, int opts, char *anchorname)
308{ 308{
309 struct pfr_buffer t; 309 struct pfr_buffer t;
310 310
311 memset(&t, 0, sizeof(t)); 311 memset(&t, 0, sizeof(t));
312 t.pfrb_type = PFRB_TRANS; 312 t.pfrb_type = PFRB_TRANS;
313 if (pfctl_add_trans(&t, PF_RULESET_SCRUB, anchorname) || 313 if (pfctl_add_trans(&t, PF_RULESET_SCRUB, anchorname) ||
314 pfctl_add_trans(&t, PF_RULESET_FILTER, anchorname) || 314 pfctl_add_trans(&t, PF_RULESET_FILTER, anchorname) ||
315 pfctl_trans(dev, &t, DIOCXBEGIN, 0) || 315 pfctl_trans(dev, &t, DIOCXBEGIN, 0) ||
316 pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) 316 pfctl_trans(dev, &t, DIOCXCOMMIT, 0))
317 err(1, "pfctl_clear_rules"); 317 err(1, "pfctl_clear_rules");
318 if ((opts & PF_OPT_QUIET) == 0) 318 if ((opts & PF_OPT_QUIET) == 0)
319 fprintf(stderr, "rules cleared\n"); 319 fprintf(stderr, "rules cleared\n");
320 return (0); 320 return (0);
321} 321}
322 322
323int 323int
324pfctl_clear_nat(int dev, int opts, char *anchorname) 324pfctl_clear_nat(int dev, int opts, char *anchorname)
325{ 325{
326 struct pfr_buffer t; 326 struct pfr_buffer t;
327 327
328 memset(&t, 0, sizeof(t)); 328 memset(&t, 0, sizeof(t));
329 t.pfrb_type = PFRB_TRANS; 329 t.pfrb_type = PFRB_TRANS;
330 if (pfctl_add_trans(&t, PF_RULESET_NAT, anchorname) || 330 if (pfctl_add_trans(&t, PF_RULESET_NAT, anchorname) ||
331 pfctl_add_trans(&t, PF_RULESET_BINAT, anchorname) || 331 pfctl_add_trans(&t, PF_RULESET_BINAT, anchorname) ||
332 pfctl_add_trans(&t, PF_RULESET_RDR, anchorname) || 332 pfctl_add_trans(&t, PF_RULESET_RDR, anchorname) ||
333 pfctl_trans(dev, &t, DIOCXBEGIN, 0) || 333 pfctl_trans(dev, &t, DIOCXBEGIN, 0) ||
334 pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) 334 pfctl_trans(dev, &t, DIOCXCOMMIT, 0))
335 err(1, "pfctl_clear_nat"); 335 err(1, "pfctl_clear_nat");
336 if ((opts & PF_OPT_QUIET) == 0) 336 if ((opts & PF_OPT_QUIET) == 0)
337 fprintf(stderr, "nat cleared\n"); 337 fprintf(stderr, "nat cleared\n");
338 return (0); 338 return (0);
339} 339}
340 340
341int 341int
342pfctl_clear_altq(int dev, int opts) 342pfctl_clear_altq(int dev, int opts)
343{ 343{
344 struct pfr_buffer t; 344 struct pfr_buffer t;
345 345
346 if (!altqsupport) 346 if (!altqsupport)
347 return (-1); 347 return (-1);
348 memset(&t, 0, sizeof(t)); 348 memset(&t, 0, sizeof(t));
349 t.pfrb_type = PFRB_TRANS; 349 t.pfrb_type = PFRB_TRANS;
350 if (pfctl_add_trans(&t, PF_RULESET_ALTQ, "") || 350 if (pfctl_add_trans(&t, PF_RULESET_ALTQ, "") ||
351 pfctl_trans(dev, &t, DIOCXBEGIN, 0) || 351 pfctl_trans(dev, &t, DIOCXBEGIN, 0) ||
352 pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) 352 pfctl_trans(dev, &t, DIOCXCOMMIT, 0))
353 err(1, "pfctl_clear_altq"); 353 err(1, "pfctl_clear_altq");
354 if ((opts & PF_OPT_QUIET) == 0) 354 if ((opts & PF_OPT_QUIET) == 0)
355 fprintf(stderr, "altq cleared\n"); 355 fprintf(stderr, "altq cleared\n");
356 return (0); 356 return (0);
357} 357}
358 358
359int 359int
360pfctl_clear_src_nodes(int dev, int opts) 360pfctl_clear_src_nodes(int dev, int opts)
361{ 361{
362 if (ioctl(dev, DIOCCLRSRCNODES)) 362 if (ioctl(dev, DIOCCLRSRCNODES))
363 err(1, "DIOCCLRSRCNODES"); 363 err(1, "DIOCCLRSRCNODES");
364 if ((opts & PF_OPT_QUIET) == 0) 364 if ((opts & PF_OPT_QUIET) == 0)
365 fprintf(stderr, "source tracking entries cleared\n"); 365 fprintf(stderr, "source tracking entries cleared\n");
366 return (0); 366 return (0);
367} 367}
368 368
369int 369int
370pfctl_clear_states(int dev, const char *iface, int opts) 370pfctl_clear_states(int dev, const char *iface, int opts)
371{ 371{
372 struct pfioc_state_kill psk; 372 struct pfioc_state_kill psk;
373 373
374 memset(&psk, 0, sizeof(psk)); 374 memset(&psk, 0, sizeof(psk));
375 if (iface != NULL && strlcpy(psk.psk_ifname, iface, 375 if (iface != NULL && strlcpy(psk.psk_ifname, iface,
376 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) 376 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
377 errx(1, "invalid interface: %s", iface); 377 errx(1, "invalid interface: %s", iface);
378 378
379 if (ioctl(dev, DIOCCLRSTATES, &psk)) 379 if (ioctl(dev, DIOCCLRSTATES, &psk))
380 err(1, "DIOCCLRSTATES"); 380 err(1, "DIOCCLRSTATES");
381 if ((opts & PF_OPT_QUIET) == 0) 381 if ((opts & PF_OPT_QUIET) == 0)
382 fprintf(stderr, "%d states cleared\n", psk.psk_af); 382 fprintf(stderr, "%d states cleared\n", psk.psk_af);
383 return (0); 383 return (0);
384} 384}
385 385
386void 386void
387pfctl_addrprefix(char *addr, struct pf_addr *mask) 387pfctl_addrprefix(char *addr, struct pf_addr *mask)
388{ 388{
389 char *p; 389 char *p;
390 const char *errstr = NULL; /* XXX gcc */ 390 const char *errstr = NULL; /* XXX gcc */
391 int prefix, ret_ga, q, r; 391 int prefix, ret_ga, q, r;
392 struct addrinfo hints, *res; 392 struct addrinfo hints, *res;
393 393
394 if ((p = strchr(addr, '/')) == NULL) 394 if ((p = strchr(addr, '/')) == NULL)
395 return; 395 return;
396 396
397 *p++ = '\0'; 397 *p++ = '\0';
398 prefix = strtonum(p, 0, 128, &errstr); 398 prefix = strtonum(p, 0, 128, &errstr);
399 if (errstr) 399 if (errstr)
400 errx(1, "prefix is %s: %s", errstr, p); 400 errx(1, "prefix is %s: %s", errstr, p);
401 401
402 bzero(&hints, sizeof(hints)); 402 bzero(&hints, sizeof(hints));
403 /* prefix only with numeric addresses */ 403 /* prefix only with numeric addresses */
404 hints.ai_flags |= AI_NUMERICHOST; 404 hints.ai_flags |= AI_NUMERICHOST;
405 405
406 if ((ret_ga = getaddrinfo(addr, NULL, &hints, &res))) { 406 if ((ret_ga = getaddrinfo(addr, NULL, &hints, &res))) {
407 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga)); 407 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
408 /* NOTREACHED */ 408 /* NOTREACHED */
409 } 409 }
410 410
411 if (res->ai_family == AF_INET && prefix > 32) 411 if (res->ai_family == AF_INET && prefix > 32)
412 errx(1, "prefix too long for AF_INET"); 412 errx(1, "prefix too long for AF_INET");
413 else if (res->ai_family == AF_INET6 && prefix > 128) 413 else if (res->ai_family == AF_INET6 && prefix > 128)
414 errx(1, "prefix too long for AF_INET6"); 414 errx(1, "prefix too long for AF_INET6");
415 415
416 q = prefix >> 3; 416 q = prefix >> 3;
417 r = prefix & 7; 417 r = prefix & 7;
418 switch (res->ai_family) { 418 switch (res->ai_family) {
419 case AF_INET: 419 case AF_INET:
420 bzero(&mask->v4, sizeof(mask->v4)); 420 bzero(&mask->v4, sizeof(mask->v4));
421 mask->v4.s_addr = htonl((u_int32_t) 421 mask->v4.s_addr = htonl((u_int32_t)
422 (0xffffffffffULL << (32 - prefix))); 422 (0xffffffffffULL << (32 - prefix)));
423 break; 423 break;
424 case AF_INET6: 424 case AF_INET6:
425 bzero(&mask->v6, sizeof(mask->v6)); 425 bzero(&mask->v6, sizeof(mask->v6));
426 if (q > 0) 426 if (q > 0)
427 memset((void *)&mask->v6, 0xff, q); 427 memset((void *)&mask->v6, 0xff, q);
428 if (r > 0) 428 if (r > 0)
429 *((u_char *)&mask->v6 + q) = 429 *((u_char *)&mask->v6 + q) =
430 (0xff00 >> r) & 0xff; 430 (0xff00 >> r) & 0xff;
431 break; 431 break;
432 } 432 }
433 freeaddrinfo(res); 433 freeaddrinfo(res);
434} 434}
435 435
436int 436int
437pfctl_kill_src_nodes(int dev, const char *iface, int opts) 437pfctl_kill_src_nodes(int dev, const char *iface, int opts)
438{ 438{
439 struct pfioc_src_node_kill psnk; 439 struct pfioc_src_node_kill psnk;
440 struct addrinfo *res[2], *resp[2]; 440 struct addrinfo *res[2], *resp[2];
441 struct sockaddr last_src, last_dst; 441 struct sockaddr last_src, last_dst;
442 int killed, sources, dests; 442 int killed, sources, dests;
443 int ret_ga; 443 int ret_ga;
444 444
445 killed = sources = dests = 0; 445 killed = sources = dests = 0;
446 446
447 memset(&psnk, 0, sizeof(psnk)); 447 memset(&psnk, 0, sizeof(psnk));
448 memset(&psnk.psnk_src.addr.v.a.mask, 0xff, 448 memset(&psnk.psnk_src.addr.v.a.mask, 0xff,
449 sizeof(psnk.psnk_src.addr.v.a.mask)); 449 sizeof(psnk.psnk_src.addr.v.a.mask));
450 memset(&last_src, 0xff, sizeof(last_src)); 450 memset(&last_src, 0xff, sizeof(last_src));
451 memset(&last_dst, 0xff, sizeof(last_dst)); 451 memset(&last_dst, 0xff, sizeof(last_dst));
452 452
453 pfctl_addrprefix(src_node_kill[0], &psnk.psnk_src.addr.v.a.mask); 453 pfctl_addrprefix(src_node_kill[0], &psnk.psnk_src.addr.v.a.mask);
454 454
455 if ((ret_ga = getaddrinfo(src_node_kill[0], NULL, NULL, &res[0]))) { 455 if ((ret_ga = getaddrinfo(src_node_kill[0], NULL, NULL, &res[0]))) {
456 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga)); 456 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
457 /* NOTREACHED */ 457 /* NOTREACHED */
458 } 458 }
459 for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) { 459 for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) {
460 if (resp[0]->ai_addr == NULL) 460 if (resp[0]->ai_addr == NULL)
461 continue; 461 continue;
462 /* We get lots of duplicates. Catch the easy ones */ 462 /* We get lots of duplicates. Catch the easy ones */
463 if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0) 463 if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0)
464 continue; 464 continue;
465 last_src = *(struct sockaddr *)resp[0]->ai_addr; 465 last_src = *(struct sockaddr *)resp[0]->ai_addr;
466 466
467 psnk.psnk_af = resp[0]->ai_family; 467 psnk.psnk_af = resp[0]->ai_family;
468 sources++; 468 sources++;
469 469
470 if (psnk.psnk_af == AF_INET) 470 if (psnk.psnk_af == AF_INET)
471 psnk.psnk_src.addr.v.a.addr.v4 = 471 psnk.psnk_src.addr.v.a.addr.v4 =
472 ((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr; 472 ((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr;
473 else if (psnk.psnk_af == AF_INET6) 473 else if (psnk.psnk_af == AF_INET6)
474 psnk.psnk_src.addr.v.a.addr.v6 = 474 psnk.psnk_src.addr.v.a.addr.v6 =
475 ((struct sockaddr_in6 *)resp[0]->ai_addr)-> 475 ((struct sockaddr_in6 *)resp[0]->ai_addr)->
476 sin6_addr; 476 sin6_addr;
477 else 477 else
478 errx(1, "Unknown address family %d", psnk.psnk_af); 478 errx(1, "Unknown address family %d", psnk.psnk_af);
479 479
480 if (src_node_killers > 1) { 480 if (src_node_killers > 1) {
481 dests = 0; 481 dests = 0;
482 memset(&psnk.psnk_dst.addr.v.a.mask, 0xff, 482 memset(&psnk.psnk_dst.addr.v.a.mask, 0xff,
483 sizeof(psnk.psnk_dst.addr.v.a.mask)); 483 sizeof(psnk.psnk_dst.addr.v.a.mask));
484 memset(&last_dst, 0xff, sizeof(last_dst)); 484 memset(&last_dst, 0xff, sizeof(last_dst));
485 pfctl_addrprefix(src_node_kill[1], 485 pfctl_addrprefix(src_node_kill[1],
486 &psnk.psnk_dst.addr.v.a.mask); 486 &psnk.psnk_dst.addr.v.a.mask);
487 if ((ret_ga = getaddrinfo(src_node_kill[1], NULL, NULL, 487 if ((ret_ga = getaddrinfo(src_node_kill[1], NULL, NULL,
488 &res[1]))) { 488 &res[1]))) {
489 errx(1, "getaddrinfo: %s", 489 errx(1, "getaddrinfo: %s",
490 gai_strerror(ret_ga)); 490 gai_strerror(ret_ga));
491 /* NOTREACHED */ 491 /* NOTREACHED */
492 } 492 }
493 for (resp[1] = res[1]; resp[1]; 493 for (resp[1] = res[1]; resp[1];
494 resp[1] = resp[1]->ai_next) { 494 resp[1] = resp[1]->ai_next) {
495 if (resp[1]->ai_addr == NULL) 495 if (resp[1]->ai_addr == NULL)
496 continue; 496 continue;
497 if (psnk.psnk_af != resp[1]->ai_family) 497 if (psnk.psnk_af != resp[1]->ai_family)
498 continue; 498 continue;
499 499
500 if (memcmp(&last_dst, resp[1]->ai_addr, 500 if (memcmp(&last_dst, resp[1]->ai_addr,
501 sizeof(last_dst)) == 0) 501 sizeof(last_dst)) == 0)
502 continue; 502 continue;
503 last_dst = *(struct sockaddr *)resp[1]->ai_addr; 503 last_dst = *(struct sockaddr *)resp[1]->ai_addr;
504 504
505 dests++; 505 dests++;
506 506
507 if (psnk.psnk_af == AF_INET) 507 if (psnk.psnk_af == AF_INET)
508 psnk.psnk_dst.addr.v.a.addr.v4 = 508 psnk.psnk_dst.addr.v.a.addr.v4 =
509 ((struct sockaddr_in *)resp[1]-> 509 ((struct sockaddr_in *)resp[1]->
510 ai_addr)->sin_addr; 510 ai_addr)->sin_addr;
511 else if (psnk.psnk_af == AF_INET6) 511 else if (psnk.psnk_af == AF_INET6)
512 psnk.psnk_dst.addr.v.a.addr.v6 = 512 psnk.psnk_dst.addr.v.a.addr.v6 =
513 ((struct sockaddr_in6 *)resp[1]-> 513 ((struct sockaddr_in6 *)resp[1]->
514 ai_addr)->sin6_addr; 514 ai_addr)->sin6_addr;
515 else 515 else
516 errx(1, "Unknown address family %d", 516 errx(1, "Unknown address family %d",
517 psnk.psnk_af); 517 psnk.psnk_af);
518 518
519 if (ioctl(dev, DIOCKILLSRCNODES, &psnk)) 519 if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
520 err(1, "DIOCKILLSRCNODES"); 520 err(1, "DIOCKILLSRCNODES");
521 killed += psnk.psnk_af; 521 killed += psnk.psnk_af;
522 /* fixup psnk.psnk_af */ 522 /* fixup psnk.psnk_af */
523 psnk.psnk_af = resp[1]->ai_family; 523 psnk.psnk_af = resp[1]->ai_family;
524 } 524 }
525 freeaddrinfo(res[1]); 525 freeaddrinfo(res[1]);
526 } else { 526 } else {
527 if (ioctl(dev, DIOCKILLSRCNODES, &psnk)) 527 if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
528 err(1, "DIOCKILLSRCNODES"); 528 err(1, "DIOCKILLSRCNODES");
529 killed += psnk.psnk_af; 529 killed += psnk.psnk_af;
530 /* fixup psnk.psnk_af */ 530 /* fixup psnk.psnk_af */
531 psnk.psnk_af = res[0]->ai_family; 531 psnk.psnk_af = res[0]->ai_family;
532 } 532 }
533 } 533 }
534 534
535 freeaddrinfo(res[0]); 535 freeaddrinfo(res[0]);
536 536
537 if ((opts & PF_OPT_QUIET) == 0) 537 if ((opts & PF_OPT_QUIET) == 0)
538 fprintf(stderr, "killed %d src nodes from %d sources and %d " 538 fprintf(stderr, "killed %d src nodes from %d sources and %d "
539 "destinations\n", killed, sources, dests); 539 "destinations\n", killed, sources, dests);
540 return (0); 540 return (0);
541} 541}
542 542
543int 543int
544pfctl_kill_states(int dev, const char *iface, int opts) 544pfctl_kill_states(int dev, const char *iface, int opts)
545{ 545{
546 struct pfioc_state_kill psk; 546 struct pfioc_state_kill psk;
547 struct addrinfo *res[2], *resp[2]; 547 struct addrinfo *res[2], *resp[2];
548 struct sockaddr last_src, last_dst; 548 struct sockaddr last_src, last_dst;
549 int killed, sources, dests; 549 int killed, sources, dests;
550 int ret_ga; 550 int ret_ga;
551 551
552 killed = sources = dests = 0; 552 killed = sources = dests = 0;
553 553
554 memset(&psk, 0, sizeof(psk)); 554 memset(&psk, 0, sizeof(psk));
555 memset(&psk.psk_src.addr.v.a.mask, 0xff, 555 memset(&psk.psk_src.addr.v.a.mask, 0xff,
556 sizeof(psk.psk_src.addr.v.a.mask)); 556 sizeof(psk.psk_src.addr.v.a.mask));
557 memset(&last_src, 0xff, sizeof(last_src)); 557 memset(&last_src, 0xff, sizeof(last_src));
558 memset(&last_dst, 0xff, sizeof(last_dst)); 558 memset(&last_dst, 0xff, sizeof(last_dst));
559 if (iface != NULL && strlcpy(psk.psk_ifname, iface, 559 if (iface != NULL && strlcpy(psk.psk_ifname, iface,
560 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) 560 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
561 errx(1, "invalid interface: %s", iface); 561 errx(1, "invalid interface: %s", iface);
562 562
563 pfctl_addrprefix(state_kill[0], &psk.psk_src.addr.v.a.mask); 563 pfctl_addrprefix(state_kill[0], &psk.psk_src.addr.v.a.mask);
564 564
565 if ((ret_ga = getaddrinfo(state_kill[0], NULL, NULL, &res[0]))) { 565 if ((ret_ga = getaddrinfo(state_kill[0], NULL, NULL, &res[0]))) {
566 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga)); 566 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
567 /* NOTREACHED */ 567 /* NOTREACHED */
568 } 568 }
569 for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) { 569 for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) {
570 if (resp[0]->ai_addr == NULL) 570 if (resp[0]->ai_addr == NULL)
571 continue; 571 continue;
572 /* We get lots of duplicates. Catch the easy ones */ 572 /* We get lots of duplicates. Catch the easy ones */
573 if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0) 573 if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0)
574 continue; 574 continue;
575 last_src = *(struct sockaddr *)resp[0]->ai_addr; 575 last_src = *(struct sockaddr *)resp[0]->ai_addr;
576 576
577 psk.psk_af = resp[0]->ai_family; 577 psk.psk_af = resp[0]->ai_family;
578 sources++; 578 sources++;
579 579
580 if (psk.psk_af == AF_INET) 580 if (psk.psk_af == AF_INET)
581 psk.psk_src.addr.v.a.addr.v4 = 581 psk.psk_src.addr.v.a.addr.v4 =
582 ((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr; 582 ((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr;
583 else if (psk.psk_af == AF_INET6) 583 else if (psk.psk_af == AF_INET6)
584 psk.psk_src.addr.v.a.addr.v6 = 584 psk.psk_src.addr.v.a.addr.v6 =
585 ((struct sockaddr_in6 *)resp[0]->ai_addr)-> 585 ((struct sockaddr_in6 *)resp[0]->ai_addr)->
586 sin6_addr; 586 sin6_addr;
587 else 587 else
588 errx(1, "Unknown address family %d", psk.psk_af); 588 errx(1, "Unknown address family %d", psk.psk_af);
589 589
590 if (state_killers > 1) { 590 if (state_killers > 1) {
591 dests = 0; 591 dests = 0;
592 memset(&psk.psk_dst.addr.v.a.mask, 0xff, 592 memset(&psk.psk_dst.addr.v.a.mask, 0xff,
593 sizeof(psk.psk_dst.addr.v.a.mask)); 593 sizeof(psk.psk_dst.addr.v.a.mask));
594 memset(&last_dst, 0xff, sizeof(last_dst)); 594 memset(&last_dst, 0xff, sizeof(last_dst));
595 pfctl_addrprefix(state_kill[1], 595 pfctl_addrprefix(state_kill[1],
596 &psk.psk_dst.addr.v.a.mask); 596 &psk.psk_dst.addr.v.a.mask);
597 if ((ret_ga = getaddrinfo(state_kill[1], NULL, NULL, 597 if ((ret_ga = getaddrinfo(state_kill[1], NULL, NULL,
598 &res[1]))) { 598 &res[1]))) {
599 errx(1, "getaddrinfo: %s", 599 errx(1, "getaddrinfo: %s",
600 gai_strerror(ret_ga)); 600 gai_strerror(ret_ga));
601 /* NOTREACHED */ 601 /* NOTREACHED */
602 } 602 }
603 for (resp[1] = res[1]; resp[1]; 603 for (resp[1] = res[1]; resp[1];
604 resp[1] = resp[1]->ai_next) { 604 resp[1] = resp[1]->ai_next) {
605 if (resp[1]->ai_addr == NULL) 605 if (resp[1]->ai_addr == NULL)
606 continue; 606 continue;
607 if (psk.psk_af != resp[1]->ai_family) 607 if (psk.psk_af != resp[1]->ai_family)
608 continue; 608 continue;
609 609
610 if (memcmp(&last_dst, resp[1]->ai_addr, 610 if (memcmp(&last_dst, resp[1]->ai_addr,
611 sizeof(last_dst)) == 0) 611 sizeof(last_dst)) == 0)
612 continue; 612 continue;
613 last_dst = *(struct sockaddr *)resp[1]->ai_addr; 613 last_dst = *(struct sockaddr *)resp[1]->ai_addr;
614 614
615 dests++; 615 dests++;
616 616
617 if (psk.psk_af == AF_INET) 617 if (psk.psk_af == AF_INET)
618 psk.psk_dst.addr.v.a.addr.v4 = 618 psk.psk_dst.addr.v.a.addr.v4 =
619 ((struct sockaddr_in *)resp[1]-> 619 ((struct sockaddr_in *)resp[1]->
620 ai_addr)->sin_addr; 620 ai_addr)->sin_addr;
621 else if (psk.psk_af == AF_INET6) 621 else if (psk.psk_af == AF_INET6)
622 psk.psk_dst.addr.v.a.addr.v6 = 622 psk.psk_dst.addr.v.a.addr.v6 =
623 ((struct sockaddr_in6 *)resp[1]-> 623 ((struct sockaddr_in6 *)resp[1]->
624 ai_addr)->sin6_addr; 624 ai_addr)->sin6_addr;
625 else 625 else
626 errx(1, "Unknown address family %d", 626 errx(1, "Unknown address family %d",
627 psk.psk_af); 627 psk.psk_af);
628 628
629 if (ioctl(dev, DIOCKILLSTATES, &psk)) 629 if (ioctl(dev, DIOCKILLSTATES, &psk))
630 err(1, "DIOCKILLSTATES"); 630 err(1, "DIOCKILLSTATES");
631 killed += psk.psk_af; 631 killed += psk.psk_af;
632 /* fixup psk.psk_af */ 632 /* fixup psk.psk_af */
633 psk.psk_af = resp[1]->ai_family; 633 psk.psk_af = resp[1]->ai_family;
634 } 634 }
635 freeaddrinfo(res[1]); 635 freeaddrinfo(res[1]);
636 } else { 636 } else {
637 if (ioctl(dev, DIOCKILLSTATES, &psk)) 637 if (ioctl(dev, DIOCKILLSTATES, &psk))
638 err(1, "DIOCKILLSTATES"); 638 err(1, "DIOCKILLSTATES");
639 killed += psk.psk_af; 639 killed += psk.psk_af;
640 /* fixup psk.psk_af */ 640 /* fixup psk.psk_af */
641 psk.psk_af = res[0]->ai_family; 641 psk.psk_af = res[0]->ai_family;
642 } 642 }
643 } 643 }
644 644
645 freeaddrinfo(res[0]); 645 freeaddrinfo(res[0]);
646 646
647 if ((opts & PF_OPT_QUIET) == 0) 647 if ((opts & PF_OPT_QUIET) == 0)
648 fprintf(stderr, "killed %d states from %d sources and %d " 648 fprintf(stderr, "killed %d states from %d sources and %d "
649 "destinations\n", killed, sources, dests); 649 "destinations\n", killed, sources, dests);
650 return (0); 650 return (0);
651} 651}
652 652
653int 653int
654pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr, 654pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr,
655 u_int32_t ticket, int r_action, char *anchorname) 655 u_int32_t ticket, int r_action, char *anchorname)
656{ 656{
657 struct pfioc_pooladdr pp; 657 struct pfioc_pooladdr pp;
658 struct pf_pooladdr *pa; 658 struct pf_pooladdr *pa;
659 u_int32_t pnr, mpnr; 659 u_int32_t pnr, mpnr;
660 660
661 memset(&pp, 0, sizeof(pp)); 661 memset(&pp, 0, sizeof(pp));
662 memcpy(pp.anchor, anchorname, sizeof(pp.anchor)); 662 memcpy(pp.anchor, anchorname, sizeof(pp.anchor));
663 pp.r_action = r_action; 663 pp.r_action = r_action;
664 pp.r_num = nr; 664 pp.r_num = nr;
665 pp.ticket = ticket; 665 pp.ticket = ticket;
666 if (ioctl(dev, DIOCGETADDRS, &pp)) { 666 if (ioctl(dev, DIOCGETADDRS, &pp)) {
667 warn("DIOCGETADDRS"); 667 warn("DIOCGETADDRS");
668 return (-1); 668 return (-1);
669 } 669 }
670 mpnr = pp.nr; 670 mpnr = pp.nr;
671 TAILQ_INIT(&pool->list); 671 TAILQ_INIT(&pool->list);
672 for (pnr = 0; pnr < mpnr; ++pnr) { 672 for (pnr = 0; pnr < mpnr; ++pnr) {
673 pp.nr = pnr; 673 pp.nr = pnr;
674 if (ioctl(dev, DIOCGETADDR, &pp)) { 674 if (ioctl(dev, DIOCGETADDR, &pp)) {
675 warn("DIOCGETADDR"); 675 warn("DIOCGETADDR");
676 return (-1); 676 return (-1);
677 } 677 }
678 pa = calloc(1, sizeof(struct pf_pooladdr)); 678 pa = calloc(1, sizeof(struct pf_pooladdr));
679 if (pa == NULL) 679 if (pa == NULL)
680 err(1, "calloc"); 680 err(1, "calloc");
681 bcopy(&pp.addr, pa, sizeof(struct pf_pooladdr)); 681 bcopy(&pp.addr, pa, sizeof(struct pf_pooladdr));
682 TAILQ_INSERT_TAIL(&pool->list, pa, entries); 682 TAILQ_INSERT_TAIL(&pool->list, pa, entries);
683 } 683 }
684 684
685 return (0); 685 return (0);
686} 686}
687 687
688void 688void
689pfctl_move_pool(struct pf_pool *src, struct pf_pool *dst) 689pfctl_move_pool(struct pf_pool *src, struct pf_pool *dst)
690{ 690{
691 struct pf_pooladdr *pa; 691 struct pf_pooladdr *pa;
692 692
693 while ((pa = TAILQ_FIRST(&src->list)) != NULL) { 693 while ((pa = TAILQ_FIRST(&src->list)) != NULL) {
694 TAILQ_REMOVE(&src->list, pa, entries); 694 TAILQ_REMOVE(&src->list, pa, entries);
695 TAILQ_INSERT_TAIL(&dst->list, pa, entries); 695 TAILQ_INSERT_TAIL(&dst->list, pa, entries);
696 } 696 }
697} 697}
698 698
699void 699void
700pfctl_clear_pool(struct pf_pool *pool) 700pfctl_clear_pool(struct pf_pool *pool)
701{ 701{
702 struct pf_pooladdr *pa; 702 struct pf_pooladdr *pa;
703 703
704 while ((pa = TAILQ_FIRST(&pool->list)) != NULL) { 704 while ((pa = TAILQ_FIRST(&pool->list)) != NULL) {
705 TAILQ_REMOVE(&pool->list, pa, entries); 705 TAILQ_REMOVE(&pool->list, pa, entries);
706 free(pa); 706 free(pa);
707 } 707 }
708} 708}
709 709
710void 710void
711pfctl_print_rule_counters(struct pf_rule *rule, int opts) 711pfctl_print_rule_counters(struct pf_rule *rule, int opts)
712{ 712{
713 if (opts & PF_OPT_DEBUG) { 713 if (opts & PF_OPT_DEBUG) {
714 const char *t[PF_SKIP_COUNT] = { "i", "d", "f", 714 const char *t[PF_SKIP_COUNT] = { "i", "d", "f",
715 "p", "sa", "sp", "da", "dp" }; 715 "p", "sa", "sp", "da", "dp" };
716 int i; 716 int i;
717 717
718 printf(" [ Skip steps: "); 718 printf(" [ Skip steps: ");
719 for (i = 0; i < PF_SKIP_COUNT; ++i) { 719 for (i = 0; i < PF_SKIP_COUNT; ++i) {
720 if (rule->skip[i].nr == rule->nr + 1) 720 if (rule->skip[i].nr == rule->nr + 1)
721 continue; 721 continue;
722 printf("%s=", t[i]); 722 printf("%s=", t[i]);
723 if (rule->skip[i].nr == -1) 723 if (rule->skip[i].nr == -1)
724 printf("end "); 724 printf("end ");
725 else 725 else
726 printf("%u ", rule->skip[i].nr); 726 printf("%u ", rule->skip[i].nr);
727 } 727 }
728 printf("]\n"); 728 printf("]\n");
729 729
730 printf(" [ queue: qname=%s qid=%u pqname=%s pqid=%u ]\n", 730 printf(" [ queue: qname=%s qid=%u pqname=%s pqid=%u ]\n",
731 rule->qname, rule->qid, rule->pqname, rule->pqid); 731 rule->qname, rule->qid, rule->pqname, rule->pqid);
732 } 732 }
733 if (opts & PF_OPT_VERBOSE) { 733 if (opts & PF_OPT_VERBOSE) {
734 printf(" [ Evaluations: %-8llu Packets: %-8llu " 734 printf(" [ Evaluations: %-8llu Packets: %-8llu "
735 "Bytes: %-10llu States: %-6u]\n", 735 "Bytes: %-10llu States: %-6u]\n",
736 (unsigned long long)rule->evaluations, 736 (unsigned long long)rule->evaluations,
737 (unsigned long long)(rule->packets[0] + 737 (unsigned long long)(rule->packets[0] +
738 rule->packets[1]), 738 rule->packets[1]),
739 (unsigned long long)(rule->bytes[0] + 739 (unsigned long long)(rule->bytes[0] +
740 rule->bytes[1]), rule->states); 740 rule->bytes[1]), rule->states);
741 if (!(opts & PF_OPT_DEBUG)) 741 if (!(opts & PF_OPT_DEBUG))
742 printf(" [ Inserted: uid %u pid %u ]\n", 742 printf(" [ Inserted: uid %u pid %u ]\n",
743 (unsigned)rule->cuid, (unsigned)rule->cpid); 743 (unsigned)rule->cuid, (unsigned)rule->cpid);
744 } 744 }
745} 745}
746 746
747void 747void
748pfctl_print_title(char *title) 748pfctl_print_title(char *title)
749{ 749{
750 if (!first_title) 750 if (!first_title)
751 printf("\n"); 751 printf("\n");
752 first_title = 0; 752 first_title = 0;
753 printf("%s\n", title); 753 printf("%s\n", title);
754} 754}
755 755
756int 756int
757pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format, 757pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
758 char *anchorname, int depth) 758 char *anchorname, int depth)
759{ 759{
760 struct pfioc_rule pr; 760 struct pfioc_rule pr;
761 u_int32_t nr, mnr, header = 0; 761 u_int32_t nr, mnr, header = 0;
762 int rule_numbers = opts & (PF_OPT_VERBOSE2 | PF_OPT_DEBUG); 762 int rule_numbers = opts & (PF_OPT_VERBOSE2 | PF_OPT_DEBUG);
763 int len = strlen(path); 763 int len = strlen(path);
764 int brace; 764 int brace;
765 char *p; 765 char *p;
766 766
767 if (path[0]) 767 if (path[0])
768 snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname); 768 snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname);
769 else 769 else
770 snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname); 770 snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname);
771 771
772 memset(&pr, 0, sizeof(pr)); 772 memset(&pr, 0, sizeof(pr));
773 memcpy(pr.anchor, path, sizeof(pr.anchor)); 773 memcpy(pr.anchor, path, sizeof(pr.anchor));
774 if (opts & PF_OPT_SHOWALL) { 774 if (opts & PF_OPT_SHOWALL) {
775 pr.rule.action = PF_PASS; 775 pr.rule.action = PF_PASS;
776 if (ioctl(dev, DIOCGETRULES, &pr)) { 776 if (ioctl(dev, DIOCGETRULES, &pr)) {
777 warn("DIOCGETRULES"); 777 warn("DIOCGETRULES");
778 goto error; 778 goto error;
779 } 779 }
780 header++; 780 header++;
781 } 781 }
782 pr.rule.action = PF_SCRUB; 782 pr.rule.action = PF_SCRUB;
783 if (ioctl(dev, DIOCGETRULES, &pr)) { 783 if (ioctl(dev, DIOCGETRULES, &pr)) {
784 warn("DIOCGETRULES"); 784 warn("DIOCGETRULES");
785 goto error; 785 goto error;
786 } 786 }
787 if (opts & PF_OPT_SHOWALL) { 787 if (opts & PF_OPT_SHOWALL) {
788 if (format == PFCTL_SHOW_RULES && (pr.nr > 0 || header)) 788 if (format == PFCTL_SHOW_RULES && (pr.nr > 0 || header))
789 pfctl_print_title("FILTER RULES:"); 789 pfctl_print_title("FILTER RULES:");
790 else if (format == PFCTL_SHOW_LABELS && labels) 790 else if (format == PFCTL_SHOW_LABELS && labels)
791 pfctl_print_title("LABEL COUNTERS:"); 791 pfctl_print_title("LABEL COUNTERS:");
792 } 792 }
793 mnr = pr.nr; 793 mnr = pr.nr;
794 if (opts & PF_OPT_CLRRULECTRS) 794 if (opts & PF_OPT_CLRRULECTRS)
795 pr.action = PF_GET_CLR_CNTR; 795 pr.action = PF_GET_CLR_CNTR;
796 796
797 for (nr = 0; nr < mnr; ++nr) { 797 for (nr = 0; nr < mnr; ++nr) {
798 pr.nr = nr; 798 pr.nr = nr;
799 if (ioctl(dev, DIOCGETRULE, &pr)) { 799 if (ioctl(dev, DIOCGETRULE, &pr)) {
800 warn("DIOCGETRULE"); 800 warn("DIOCGETRULE");
801 goto error; 801 goto error;
802 } 802 }
803 803
804 if (pfctl_get_pool(dev, &pr.rule.rpool, 804 if (pfctl_get_pool(dev, &pr.rule.rpool,
805 nr, pr.ticket, PF_SCRUB, path) != 0) 805 nr, pr.ticket, PF_SCRUB, path) != 0)
806 goto error; 806 goto error;
807 807
808 switch (format) { 808 switch (format) {
809 case PFCTL_SHOW_LABELS: 809 case PFCTL_SHOW_LABELS:
810 if (pr.rule.label[0]) { 810 if (pr.rule.label[0]) {
811 printf("%s ", pr.rule.label); 811 printf("%s ", pr.rule.label);
812 printf("%llu %llu %llu %llu %llu %llu %llu\n", 812 printf("%llu %llu %llu %llu %llu %llu %llu\n",
813 (unsigned long long)pr.rule.evaluations, 813 (unsigned long long)pr.rule.evaluations,
814 (unsigned long long)(pr.rule.packets[0] + 814 (unsigned long long)(pr.rule.packets[0] +
815 pr.rule.packets[1]), 815 pr.rule.packets[1]),
816 (unsigned long long)(pr.rule.bytes[0] + 816 (unsigned long long)(pr.rule.bytes[0] +
817 pr.rule.bytes[1]), 817 pr.rule.bytes[1]),
818 (unsigned long long)pr.rule.packets[0], 818 (unsigned long long)pr.rule.packets[0],
819 (unsigned long long)pr.rule.bytes[0], 819 (unsigned long long)pr.rule.bytes[0],
820 (unsigned long long)pr.rule.packets[1], 820 (unsigned long long)pr.rule.packets[1],
821 (unsigned long long)pr.rule.bytes[1]); 821 (unsigned long long)pr.rule.bytes[1]);
822 } 822 }
823 break; 823 break;
824 case PFCTL_SHOW_RULES: 824 case PFCTL_SHOW_RULES:
825 if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL)) 825 if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL))
826 labels = 1; 826 labels = 1;
827 print_rule(&pr.rule, pr.anchor_call, rule_numbers); 827 print_rule(&pr.rule, pr.anchor_call, rule_numbers);
828 printf("\n"); 828 printf("\n");
829 pfctl_print_rule_counters(&pr.rule, opts); 829 pfctl_print_rule_counters(&pr.rule, opts);
830 break; 830 break;
831 case PFCTL_SHOW_NOTHING: 831 case PFCTL_SHOW_NOTHING:
832 break; 832 break;
833 } 833 }
834 pfctl_clear_pool(&pr.rule.rpool); 834 pfctl_clear_pool(&pr.rule.rpool);
835 } 835 }
836 pr.rule.action = PF_PASS; 836 pr.rule.action = PF_PASS;
837 if (ioctl(dev, DIOCGETRULES, &pr)) { 837 if (ioctl(dev, DIOCGETRULES, &pr)) {
838 warn("DIOCGETRULES"); 838 warn("DIOCGETRULES");
839 goto error; 839 goto error;
840 } 840 }
841 mnr = pr.nr; 841 mnr = pr.nr;
842 for (nr = 0; nr < mnr; ++nr) { 842 for (nr = 0; nr < mnr; ++nr) {
843 pr.nr = nr; 843 pr.nr = nr;
844 if (ioctl(dev, DIOCGETRULE, &pr)) { 844 if (ioctl(dev, DIOCGETRULE, &pr)) {
845 warn("DIOCGETRULE"); 845 warn("DIOCGETRULE");
846 goto error; 846 goto error;
847 } 847 }
848 848
849 if (pfctl_get_pool(dev, &pr.rule.rpool, 849 if (pfctl_get_pool(dev, &pr.rule.rpool,
850 nr, pr.ticket, PF_PASS, path) != 0) 850 nr, pr.ticket, PF_PASS, path) != 0)
851 goto error; 851 goto error;
852 852
853 switch (format) { 853 switch (format) {
854 case PFCTL_SHOW_LABELS: 854 case PFCTL_SHOW_LABELS:
855 if (pr.rule.label[0]) { 855 if (pr.rule.label[0]) {
856 printf("%s ", pr.rule.label); 856 printf("%s ", pr.rule.label);
857 printf("%llu %llu %llu %llu %llu %llu %llu\n", 857 printf("%llu %llu %llu %llu %llu %llu %llu\n",
858 (unsigned long long)pr.rule.evaluations, 858 (unsigned long long)pr.rule.evaluations,
859 (unsigned long long)(pr.rule.packets[0] + 859 (unsigned long long)(pr.rule.packets[0] +
860 pr.rule.packets[1]), 860 pr.rule.packets[1]),
861 (unsigned long long)(pr.rule.bytes[0] + 861 (unsigned long long)(pr.rule.bytes[0] +
862 pr.rule.bytes[1]), 862 pr.rule.bytes[1]),
863 (unsigned long long)pr.rule.packets[0], 863 (unsigned long long)pr.rule.packets[0],
864 (unsigned long long)pr.rule.bytes[0], 864 (unsigned long long)pr.rule.bytes[0],
865 (unsigned long long)pr.rule.packets[1], 865 (unsigned long long)pr.rule.packets[1],
866 (unsigned long long)pr.rule.bytes[1]); 866 (unsigned long long)pr.rule.bytes[1]);
867 } 867 }
868 break; 868 break;
869 case PFCTL_SHOW_RULES: 869 case PFCTL_SHOW_RULES:
870 brace = 0; 870 brace = 0;
871 if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL)) 871 if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL))
872 labels = 1; 872 labels = 1;
873 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 873 INDENT(depth, !(opts & PF_OPT_VERBOSE));
874 if (pr.anchor_call[0] && 874 if (pr.anchor_call[0] &&
875 ((((p = strrchr(pr.anchor_call, '_')) != NULL) && 875 ((((p = strrchr(pr.anchor_call, '_')) != NULL) &&
876 ((void *)p == (void *)pr.anchor_call || 876 ((void *)p == (void *)pr.anchor_call ||
877 *(--p) == '/')) || (opts & PF_OPT_RECURSE))) { 877 *(--p) == '/')) || (opts & PF_OPT_RECURSE))) {
878 brace++; 878 brace++;
879 if ((p = strrchr(pr.anchor_call, '/')) != 879 if ((p = strrchr(pr.anchor_call, '/')) !=
880 NULL) 880 NULL)
881 p++; 881 p++;
882 else 882 else
883 p = &pr.anchor_call[0]; 883 p = &pr.anchor_call[0];
884 } else 884 } else
885 p = &pr.anchor_call[0]; 885 p = &pr.anchor_call[0];
886  886
887 print_rule(&pr.rule, p, rule_numbers); 887 print_rule(&pr.rule, p, rule_numbers);
888 if (brace) 888 if (brace)
889 printf(" {\n"); 889 printf(" {\n");
890 else 890 else
891 printf("\n"); 891 printf("\n");
892 pfctl_print_rule_counters(&pr.rule, opts); 892 pfctl_print_rule_counters(&pr.rule, opts);
893 if (brace) {  893 if (brace) {
894 pfctl_show_rules(dev, path, opts, format, 894 pfctl_show_rules(dev, path, opts, format,
895 p, depth + 1); 895 p, depth + 1);
896 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 896 INDENT(depth, !(opts & PF_OPT_VERBOSE));
897 printf("}\n"); 897 printf("}\n");
898 } 898 }
899 break; 899 break;
900 case PFCTL_SHOW_NOTHING: 900 case PFCTL_SHOW_NOTHING:
901 break; 901 break;
902 } 902 }
903 pfctl_clear_pool(&pr.rule.rpool); 903 pfctl_clear_pool(&pr.rule.rpool);
904 } 904 }
905 path[len] = '\0'; 905 path[len] = '\0';
906 return (0); 906 return (0);
907 907
908 error: 908 error:
909 path[len] = '\0'; 909 path[len] = '\0';
910 return (-1); 910 return (-1);
911} 911}
912 912
913int 913int
914pfctl_show_nat(int dev, int opts, char *anchorname) 914pfctl_show_nat(int dev, int opts, char *anchorname)
915{ 915{
916 struct pfioc_rule pr; 916 struct pfioc_rule pr;
917 u_int32_t mnr, nr; 917 u_int32_t mnr, nr;
918 static int nattype[3] = { PF_NAT, PF_RDR, PF_BINAT }; 918 static int nattype[3] = { PF_NAT, PF_RDR, PF_BINAT };
919 int i, dotitle = opts & PF_OPT_SHOWALL; 919 int i, dotitle = opts & PF_OPT_SHOWALL;
920 920
921 memset(&pr, 0, sizeof(pr)); 921 memset(&pr, 0, sizeof(pr));
922 memcpy(pr.anchor, anchorname, sizeof(pr.anchor)); 922 memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
923 for (i = 0; i < 3; i++) { 923 for (i = 0; i < 3; i++) {
924 pr.rule.action = nattype[i]; 924 pr.rule.action = nattype[i];
925 if (ioctl(dev, DIOCGETRULES, &pr)) { 925 if (ioctl(dev, DIOCGETRULES, &pr)) {
926 warn("DIOCGETRULES"); 926 warn("DIOCGETRULES");
927 return (-1); 927 return (-1);
928 } 928 }
929 mnr = pr.nr; 929 mnr = pr.nr;
930 for (nr = 0; nr < mnr; ++nr) { 930 for (nr = 0; nr < mnr; ++nr) {
931 pr.nr = nr; 931 pr.nr = nr;
932 if (ioctl(dev, DIOCGETRULE, &pr)) { 932 if (ioctl(dev, DIOCGETRULE, &pr)) {
933 warn("DIOCGETRULE"); 933 warn("DIOCGETRULE");
934 return (-1); 934 return (-1);
935 } 935 }
936 if (pfctl_get_pool(dev, &pr.rule.rpool, nr, 936 if (pfctl_get_pool(dev, &pr.rule.rpool, nr,
937 pr.ticket, nattype[i], anchorname) != 0) 937 pr.ticket, nattype[i], anchorname) != 0)
938 return (-1); 938 return (-1);
939 if (dotitle) { 939 if (dotitle) {
940 pfctl_print_title("TRANSLATION RULES:"); 940 pfctl_print_title("TRANSLATION RULES:");
941 dotitle = 0; 941 dotitle = 0;
942 } 942 }
943 print_rule(&pr.rule, pr.anchor_call, 943 print_rule(&pr.rule, pr.anchor_call,
944 opts & PF_OPT_VERBOSE2); 944 opts & PF_OPT_VERBOSE2);
945 printf("\n"); 945 printf("\n");
946 pfctl_print_rule_counters(&pr.rule, opts); 946 pfctl_print_rule_counters(&pr.rule, opts);
947 pfctl_clear_pool(&pr.rule.rpool); 947 pfctl_clear_pool(&pr.rule.rpool);
948 } 948 }
949 } 949 }
950 return (0); 950 return (0);
951} 951}
952 952
953int 953int
954pfctl_show_src_nodes(int dev, int opts) 954pfctl_show_src_nodes(int dev, int opts)
955{ 955{
956 struct pfioc_src_nodes psn; 956 struct pfioc_src_nodes psn;
957 struct pf_src_node *p; 957 struct pf_src_node *p;
958 char *inbuf = NULL, *newinbuf = NULL; 958 char *inbuf = NULL, *newinbuf = NULL;
959 unsigned len = 0; 959 unsigned len = 0;
960 int i; 960 int i;
961 961
962 memset(&psn, 0, sizeof(psn)); 962 memset(&psn, 0, sizeof(psn));
963 for (;;) { 963 for (;;) {
964 psn.psn_len = len; 964 psn.psn_len = len;
965 if (len) { 965 if (len) {
966 newinbuf = realloc(inbuf, len); 966 newinbuf = realloc(inbuf, len);
967 if (newinbuf == NULL) 967 if (newinbuf == NULL)
968 err(1, "realloc"); 968 err(1, "realloc");
969 psn.psn_buf = inbuf = newinbuf; 969 psn.psn_buf = inbuf = newinbuf;
970 } 970 }
971 if (ioctl(dev, DIOCGETSRCNODES, &psn) < 0) { 971 if (ioctl(dev, DIOCGETSRCNODES, &psn) < 0) {
972 warn("DIOCGETSRCNODES"); 972 warn("DIOCGETSRCNODES");
973 free(inbuf); 973 free(inbuf);
974 return (-1); 974 return (-1);
975 } 975 }
976 if (psn.psn_len + sizeof(struct pfioc_src_nodes) < len) 976 if (psn.psn_len + sizeof(struct pfioc_src_nodes) < len)
977 break; 977 break;
978 if (len == 0 && psn.psn_len == 0) 978 if (len == 0 && psn.psn_len == 0)
979 goto done; 979 goto done;
980 if (len == 0 && psn.psn_len != 0) 980 if (len == 0 && psn.psn_len != 0)
981 len = psn.psn_len; 981 len = psn.psn_len;
982 if (psn.psn_len == 0) 982 if (psn.psn_len == 0)
983 goto done; /* no src_nodes */ 983 goto done; /* no src_nodes */
984 len *= 2; 984 len *= 2;
985 } 985 }
986 p = psn.psn_src_nodes; 986 p = psn.psn_src_nodes;
987 if (psn.psn_len > 0 && (opts & PF_OPT_SHOWALL)) 987 if (psn.psn_len > 0 && (opts & PF_OPT_SHOWALL))
988 pfctl_print_title("SOURCE TRACKING NODES:"); 988 pfctl_print_title("SOURCE TRACKING NODES:");
989 for (i = 0; i < psn.psn_len; i += sizeof(*p)) { 989 for (i = 0; i < psn.psn_len; i += sizeof(*p)) {
990 print_src_node(p, opts); 990 print_src_node(p, opts);
991 p++; 991 p++;
992 } 992 }
993done: 993done:
994 free(inbuf); 994 free(inbuf);
995 return (0); 995 return (0);
996} 996}
997 997
998int 998int
999pfctl_show_states(int dev, const char *iface, int opts) 999pfctl_show_states(int dev, const char *iface, int opts)
1000{ 1000{
1001 struct pfioc_states ps; 1001 struct pfioc_states ps;
1002 struct pfsync_state *p; 1002 struct pfsync_state *p;
1003 char *inbuf = NULL, *newinbuf = NULL; 1003 char *inbuf = NULL, *newinbuf = NULL;
1004 unsigned len = 0; 1004 unsigned len = 0;
1005 int i, dotitle = (opts & PF_OPT_SHOWALL); 1005 int i, dotitle = (opts & PF_OPT_SHOWALL);
1006 1006
1007 memset(&ps, 0, sizeof(ps)); 1007 memset(&ps, 0, sizeof(ps));
1008 for (;;) { 1008 for (;;) {
1009 ps.ps_len = len; 1009 ps.ps_len = len;
1010 if (len) { 1010 if (len) {
1011 newinbuf = realloc(inbuf, len); 1011 newinbuf = realloc(inbuf, len);
1012 if (newinbuf == NULL) 1012 if (newinbuf == NULL)
1013 err(1, "realloc"); 1013 err(1, "realloc");
1014 ps.ps_buf = inbuf = newinbuf; 1014 ps.ps_buf = inbuf = newinbuf;
1015 } 1015 }
1016 if (ioctl(dev, DIOCGETSTATES, &ps) < 0) { 1016 if (ioctl(dev, DIOCGETSTATES, &ps) < 0) {
1017 warn("DIOCGETSTATES"); 1017 warn("DIOCGETSTATES");
1018 free(inbuf); 1018 free(inbuf);
1019 return (-1); 1019 return (-1);
1020 } 1020 }
1021 if (ps.ps_len + sizeof(struct pfioc_states) < len) 1021 if (ps.ps_len + sizeof(struct pfioc_states) < len)
1022 break; 1022 break;
1023 if (len == 0 && ps.ps_len == 0) 1023 if (len == 0 && ps.ps_len == 0)
1024 goto done; 1024 goto done;
1025 if (len == 0 && ps.ps_len != 0) 1025 if (len == 0 && ps.ps_len != 0)
1026 len = ps.ps_len; 1026 len = ps.ps_len;
1027 if (ps.ps_len == 0) 1027 if (ps.ps_len == 0)
1028 goto done; /* no states */ 1028 goto done; /* no states */
1029 len *= 2; 1029 len *= 2;
1030 } 1030 }
1031 p = ps.ps_states; 1031 p = ps.ps_states;
1032 for (i = 0; i < ps.ps_len; i += sizeof(*p), p++) { 1032 for (i = 0; i < ps.ps_len; i += sizeof(*p), p++) {
1033 if (iface != NULL && strcmp(p->ifname, iface)) 1033 if (iface != NULL && strcmp(p->ifname, iface))
1034 continue; 1034 continue;
1035 if (dotitle) { 1035 if (dotitle) {
1036 pfctl_print_title("STATES:"); 1036 pfctl_print_title("STATES:");
1037 dotitle = 0; 1037 dotitle = 0;
1038 } 1038 }
1039 print_state(p, opts); 1039 print_state(p, opts);
1040 } 1040 }
1041done: 1041done:
1042 free(inbuf); 1042 free(inbuf);
1043 return (0); 1043 return (0);
1044} 1044}
1045 1045
1046int 1046int
1047pfctl_show_status(int dev, int opts) 1047pfctl_show_status(int dev, int opts)
1048{ 1048{
1049 struct pf_status status; 1049 struct pf_status status;
1050 1050
1051 if (ioctl(dev, DIOCGETSTATUS, &status)) { 1051 if (ioctl(dev, DIOCGETSTATUS, &status)) {
1052 warn("DIOCGETSTATUS"); 1052 warn("DIOCGETSTATUS");
1053 return (-1); 1053 return (-1);
1054 } 1054 }
1055 if (opts & PF_OPT_SHOWALL) 1055 if (opts & PF_OPT_SHOWALL)
1056 pfctl_print_title("INFO:"); 1056 pfctl_print_title("INFO:");
1057 print_status(&status, opts); 1057 print_status(&status, opts);
1058 return (0); 1058 return (0);
1059} 1059}
1060 1060
1061int 1061int
1062pfctl_show_timeouts(int dev, int opts) 1062pfctl_show_timeouts(int dev, int opts)
1063{ 1063{
1064 struct pfioc_tm pt; 1064 struct pfioc_tm pt;
1065 int i; 1065 int i;
1066 1066
1067 if (opts & PF_OPT_SHOWALL) 1067 if (opts & PF_OPT_SHOWALL)
1068 pfctl_print_title("TIMEOUTS:"); 1068 pfctl_print_title("TIMEOUTS:");
1069 memset(&pt, 0, sizeof(pt)); 1069 memset(&pt, 0, sizeof(pt));
1070 for (i = 0; pf_timeouts[i].name; i++) { 1070 for (i = 0; pf_timeouts[i].name; i++) {
1071 pt.timeout = pf_timeouts[i].timeout; 1071 pt.timeout = pf_timeouts[i].timeout;
1072 if (ioctl(dev, DIOCGETTIMEOUT, &pt)) 1072 if (ioctl(dev, DIOCGETTIMEOUT, &pt))
1073 err(1, "DIOCGETTIMEOUT"); 1073 err(1, "DIOCGETTIMEOUT");
1074 printf("%-20s %10d", pf_timeouts[i].name, pt.seconds); 1074 printf("%-20s %10d", pf_timeouts[i].name, pt.seconds);
1075 if (pf_timeouts[i].timeout >= PFTM_ADAPTIVE_START && 1075 if (pf_timeouts[i].timeout >= PFTM_ADAPTIVE_START &&
1076 pf_timeouts[i].timeout <= PFTM_ADAPTIVE_END) 1076 pf_timeouts[i].timeout <= PFTM_ADAPTIVE_END)
1077 printf(" states"); 1077 printf(" states");
1078 else 1078 else
1079 printf("s"); 1079 printf("s");
1080 printf("\n"); 1080 printf("\n");
1081 } 1081 }
1082 return (0); 1082 return (0);
1083 1083
1084} 1084}
1085 1085
1086int 1086int
1087pfctl_show_limits(int dev, int opts) 1087pfctl_show_limits(int dev, int opts)
1088{ 1088{
1089 struct pfioc_limit pl; 1089 struct pfioc_limit pl;
1090 int i; 1090 int i;
1091 1091
1092 if (opts & PF_OPT_SHOWALL) 1092 if (opts & PF_OPT_SHOWALL)
1093 pfctl_print_title("LIMITS:"); 1093 pfctl_print_title("LIMITS:");
1094 memset(&pl, 0, sizeof(pl)); 1094 memset(&pl, 0, sizeof(pl));
1095 for (i = 0; pf_limits[i].name; i++) { 1095 for (i = 0; pf_limits[i].name; i++) {
1096 pl.index = pf_limits[i].index; 1096 pl.index = pf_limits[i].index;
1097 if (ioctl(dev, DIOCGETLIMIT, &pl)) 1097 if (ioctl(dev, DIOCGETLIMIT, &pl))
1098 err(1, "DIOCGETLIMIT"); 1098 err(1, "DIOCGETLIMIT");
1099 printf("%-13s ", pf_limits[i].name); 1099 printf("%-13s ", pf_limits[i].name);