ipf.c revision 1.2 1 1.2 darrenr /* $NetBSD: ipf.c,v 1.2 2012/07/22 14:27:51 darrenr Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.2 darrenr * Copyright (C) 2012 by Darren Reed.
5 1.1 christos *
6 1.1 christos * See the IPFILTER.LICENCE file for details on licencing.
7 1.1 christos */
8 1.1 christos #ifdef __FreeBSD__
9 1.1 christos # ifndef __FreeBSD_cc_version
10 1.1 christos # include <osreldate.h>
11 1.1 christos # else
12 1.1 christos # if __FreeBSD_cc_version < 430000
13 1.1 christos # include <osreldate.h>
14 1.1 christos # endif
15 1.1 christos # endif
16 1.1 christos #endif
17 1.1 christos #include "ipf.h"
18 1.1 christos #include <fcntl.h>
19 1.1 christos #include <ctype.h>
20 1.1 christos #include <sys/ioctl.h>
21 1.1 christos #include "netinet/ipl.h"
22 1.1 christos
23 1.1 christos #if !defined(lint)
24 1.1 christos static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
25 1.2 darrenr static const char rcsid[] = "@(#)Id: ipf.c,v 1.1.1.2 2012/07/22 13:44:51 darrenr Exp $";
26 1.1 christos #endif
27 1.1 christos
28 1.1 christos #if !defined(__SVR4) && defined(__GNUC__)
29 1.1 christos extern char *index __P((const char *, int));
30 1.1 christos #endif
31 1.1 christos
32 1.1 christos extern char *optarg;
33 1.1 christos extern int optind;
34 1.1 christos extern frentry_t *frtop;
35 1.1 christos
36 1.1 christos
37 1.1 christos void ipf_frsync __P((void));
38 1.1 christos void zerostats __P((void));
39 1.1 christos int main __P((int, char *[]));
40 1.1 christos
41 1.1 christos int opts = 0;
42 1.1 christos int outputc = 0;
43 1.1 christos int use_inet6 = 0;
44 1.2 darrenr int exitstatus = 0;
45 1.1 christos
46 1.2 darrenr static void procfile __P((char *));
47 1.1 christos static void flushfilter __P((char *, int *));
48 1.1 christos static void set_state __P((u_int));
49 1.1 christos static void showstats __P((friostat_t *));
50 1.1 christos static void packetlogon __P((char *));
51 1.1 christos static void swapactive __P((void));
52 1.1 christos static int opendevice __P((char *, int));
53 1.1 christos static void closedevice __P((void));
54 1.1 christos static char *ipfname = IPL_NAME;
55 1.1 christos static void usage __P((void));
56 1.1 christos static int showversion __P((void));
57 1.1 christos static int get_flags __P((void));
58 1.2 darrenr static int ipf_interceptadd __P((int, ioctlfunc_t, void *));
59 1.1 christos
60 1.1 christos static int fd = -1;
61 1.1 christos static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
62 1.1 christos ioctl, ioctl, ioctl,
63 1.1 christos ioctl, ioctl };
64 1.1 christos
65 1.1 christos
66 1.1 christos static void usage()
67 1.1 christos {
68 1.1 christos fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n",
69 1.1 christos "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]",
70 1.1 christos "[-f filename] [-T <tuneopts>]");
71 1.1 christos exit(1);
72 1.1 christos }
73 1.1 christos
74 1.1 christos
75 1.1 christos int main(argc,argv)
76 1.1 christos int argc;
77 1.1 christos char *argv[];
78 1.1 christos {
79 1.1 christos int c, *filter = NULL;
80 1.1 christos
81 1.1 christos if (argc < 2)
82 1.1 christos usage();
83 1.1 christos
84 1.1 christos assigndefined(getenv("IPF_PREDEFINED"));
85 1.1 christos
86 1.1 christos while ((c = getopt(argc, argv, "46Ac:dDEf:F:Il:m:noPrRsT:vVyzZ")) != -1) {
87 1.1 christos switch (c)
88 1.1 christos {
89 1.1 christos case '?' :
90 1.1 christos usage();
91 1.1 christos break;
92 1.1 christos case '4' :
93 1.1 christos use_inet6 = -1;
94 1.1 christos break;
95 1.1 christos case '6' :
96 1.1 christos use_inet6 = 1;
97 1.1 christos break;
98 1.1 christos case 'A' :
99 1.1 christos opts &= ~OPT_INACTIVE;
100 1.1 christos break;
101 1.1 christos case 'c' :
102 1.1 christos if (strcmp(optarg, "c") == 0)
103 1.1 christos outputc = 1;
104 1.1 christos break;
105 1.1 christos case 'E' :
106 1.1 christos set_state((u_int)1);
107 1.1 christos break;
108 1.1 christos case 'D' :
109 1.1 christos set_state((u_int)0);
110 1.1 christos break;
111 1.1 christos case 'd' :
112 1.1 christos opts ^= OPT_DEBUG;
113 1.1 christos break;
114 1.1 christos case 'f' :
115 1.2 darrenr procfile(optarg);
116 1.1 christos break;
117 1.1 christos case 'F' :
118 1.1 christos flushfilter(optarg, filter);
119 1.1 christos break;
120 1.1 christos case 'I' :
121 1.1 christos opts ^= OPT_INACTIVE;
122 1.1 christos break;
123 1.1 christos case 'l' :
124 1.1 christos packetlogon(optarg);
125 1.1 christos break;
126 1.1 christos case 'm' :
127 1.1 christos filter = parseipfexpr(optarg, NULL);
128 1.1 christos break;
129 1.1 christos case 'n' :
130 1.1 christos opts ^= OPT_DONOTHING|OPT_DONTOPEN;
131 1.1 christos break;
132 1.1 christos case 'o' :
133 1.1 christos break;
134 1.1 christos case 'P' :
135 1.1 christos ipfname = IPAUTH_NAME;
136 1.1 christos break;
137 1.1 christos case 'R' :
138 1.1 christos opts ^= OPT_NORESOLVE;
139 1.1 christos break;
140 1.1 christos case 'r' :
141 1.1 christos opts ^= OPT_REMOVE;
142 1.1 christos break;
143 1.1 christos case 's' :
144 1.1 christos swapactive();
145 1.1 christos break;
146 1.1 christos case 'T' :
147 1.1 christos if (opendevice(ipfname, 1) >= 0)
148 1.1 christos ipf_dotuning(fd, optarg, ioctl);
149 1.1 christos break;
150 1.1 christos case 'v' :
151 1.1 christos opts += OPT_VERBOSE;
152 1.1 christos break;
153 1.1 christos case 'V' :
154 1.1 christos if (showversion())
155 1.1 christos exit(1);
156 1.1 christos break;
157 1.1 christos case 'y' :
158 1.1 christos ipf_frsync();
159 1.1 christos break;
160 1.1 christos case 'z' :
161 1.1 christos opts ^= OPT_ZERORULEST;
162 1.1 christos break;
163 1.1 christos case 'Z' :
164 1.1 christos zerostats();
165 1.1 christos break;
166 1.1 christos }
167 1.1 christos }
168 1.1 christos
169 1.1 christos if (optind < 2)
170 1.1 christos usage();
171 1.1 christos
172 1.1 christos if (fd != -1)
173 1.1 christos (void) close(fd);
174 1.1 christos
175 1.2 darrenr return(exitstatus);
176 1.1 christos /* NOTREACHED */
177 1.1 christos }
178 1.1 christos
179 1.1 christos
180 1.1 christos static int opendevice(ipfdev, check)
181 1.1 christos char *ipfdev;
182 1.1 christos int check;
183 1.1 christos {
184 1.1 christos if (opts & OPT_DONOTHING)
185 1.1 christos return -2;
186 1.1 christos
187 1.1 christos if (check && checkrev(ipfname) == -1) {
188 1.1 christos fprintf(stderr, "User/kernel version check failed\n");
189 1.1 christos return -2;
190 1.1 christos }
191 1.1 christos
192 1.1 christos if (!ipfdev)
193 1.1 christos ipfdev = ipfname;
194 1.1 christos
195 1.1 christos if (fd == -1)
196 1.1 christos if ((fd = open(ipfdev, O_RDWR)) == -1)
197 1.1 christos if ((fd = open(ipfdev, O_RDONLY)) == -1)
198 1.1 christos ipferror(fd, "open device");
199 1.1 christos return fd;
200 1.1 christos }
201 1.1 christos
202 1.1 christos
203 1.1 christos static void closedevice()
204 1.1 christos {
205 1.1 christos close(fd);
206 1.1 christos fd = -1;
207 1.1 christos }
208 1.1 christos
209 1.1 christos
210 1.1 christos static int get_flags()
211 1.1 christos {
212 1.1 christos int i = 0;
213 1.1 christos
214 1.1 christos if ((opendevice(ipfname, 1) != -2) &&
215 1.1 christos (ioctl(fd, SIOCGETFF, &i) == -1)) {
216 1.1 christos ipferror(fd, "SIOCGETFF");
217 1.1 christos return 0;
218 1.1 christos }
219 1.1 christos return i;
220 1.1 christos }
221 1.1 christos
222 1.1 christos
223 1.1 christos static void set_state(enable)
224 1.1 christos u_int enable;
225 1.1 christos {
226 1.1 christos if (opendevice(ipfname, 0) != -2) {
227 1.1 christos if (ioctl(fd, SIOCFRENB, &enable) == -1) {
228 1.1 christos if (errno == EBUSY) {
229 1.1 christos fprintf(stderr,
230 1.1 christos "IP FIlter: already initialized\n");
231 1.1 christos } else {
232 1.1 christos ipferror(fd, "SIOCFRENB");
233 1.1 christos }
234 1.1 christos }
235 1.1 christos }
236 1.1 christos return;
237 1.1 christos }
238 1.1 christos
239 1.1 christos
240 1.2 darrenr static void procfile(file)
241 1.2 darrenr char *file;
242 1.1 christos {
243 1.1 christos (void) opendevice(ipfname, 1);
244 1.1 christos
245 1.1 christos initparse();
246 1.1 christos
247 1.1 christos ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file);
248 1.1 christos
249 1.1 christos if (outputc) {
250 1.1 christos printC(0);
251 1.1 christos printC(1);
252 1.1 christos emit(-1, -1, NULL, NULL);
253 1.1 christos }
254 1.1 christos }
255 1.1 christos
256 1.1 christos
257 1.2 darrenr static int ipf_interceptadd(fd, ioctlfunc, ptr)
258 1.1 christos int fd;
259 1.1 christos ioctlfunc_t ioctlfunc;
260 1.1 christos void *ptr;
261 1.1 christos {
262 1.1 christos if (outputc)
263 1.1 christos printc(ptr);
264 1.1 christos
265 1.2 darrenr if (ipf_addrule(fd, ioctlfunc, ptr) != 0)
266 1.2 darrenr exitstatus = 1;
267 1.2 darrenr return 0;
268 1.1 christos }
269 1.1 christos
270 1.1 christos
271 1.1 christos static void packetlogon(opt)
272 1.1 christos char *opt;
273 1.1 christos {
274 1.1 christos int flag, xfd, logopt, change = 0;
275 1.1 christos
276 1.1 christos flag = get_flags();
277 1.1 christos if (flag != 0) {
278 1.1 christos if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
279 1.1 christos printf("log flag is currently %#x\n", flag);
280 1.1 christos }
281 1.1 christos
282 1.1 christos flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK);
283 1.1 christos
284 1.1 christos if (strstr(opt, "pass")) {
285 1.1 christos flag |= FF_LOGPASS;
286 1.1 christos if (opts & OPT_VERBOSE)
287 1.1 christos printf("set log flag: pass\n");
288 1.1 christos change = 1;
289 1.1 christos }
290 1.1 christos if (strstr(opt, "nomatch")) {
291 1.1 christos flag |= FF_LOGNOMATCH;
292 1.1 christos if (opts & OPT_VERBOSE)
293 1.1 christos printf("set log flag: nomatch\n");
294 1.1 christos change = 1;
295 1.1 christos }
296 1.1 christos if (strstr(opt, "block") || index(opt, 'd')) {
297 1.1 christos flag |= FF_LOGBLOCK;
298 1.1 christos if (opts & OPT_VERBOSE)
299 1.1 christos printf("set log flag: block\n");
300 1.1 christos change = 1;
301 1.1 christos }
302 1.1 christos if (strstr(opt, "none")) {
303 1.1 christos if (opts & OPT_VERBOSE)
304 1.1 christos printf("disable all log flags\n");
305 1.1 christos change = 1;
306 1.1 christos }
307 1.1 christos
308 1.1 christos if (change == 1) {
309 1.1 christos if (opendevice(ipfname, 1) != -2 &&
310 1.1 christos (ioctl(fd, SIOCSETFF, &flag) != 0))
311 1.1 christos ipferror(fd, "ioctl(SIOCSETFF)");
312 1.1 christos }
313 1.1 christos
314 1.1 christos if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
315 1.1 christos flag = get_flags();
316 1.1 christos printf("log flags are now %#x\n", flag);
317 1.1 christos }
318 1.1 christos
319 1.1 christos if (strstr(opt, "state")) {
320 1.1 christos if (opts & OPT_VERBOSE)
321 1.1 christos printf("set state log flag\n");
322 1.1 christos xfd = open(IPSTATE_NAME, O_RDWR);
323 1.1 christos if (xfd >= 0) {
324 1.1 christos logopt = 0;
325 1.1 christos if (ioctl(xfd, SIOCGETLG, &logopt))
326 1.1 christos ipferror(fd, "ioctl(SIOCGETLG)");
327 1.1 christos else {
328 1.1 christos logopt = 1 - logopt;
329 1.1 christos if (ioctl(xfd, SIOCSETLG, &logopt))
330 1.1 christos ipferror(xfd, "ioctl(SIOCSETLG)");
331 1.1 christos }
332 1.1 christos close(xfd);
333 1.1 christos }
334 1.1 christos }
335 1.1 christos
336 1.1 christos if (strstr(opt, "nat")) {
337 1.1 christos if (opts & OPT_VERBOSE)
338 1.1 christos printf("set nat log flag\n");
339 1.1 christos xfd = open(IPNAT_NAME, O_RDWR);
340 1.1 christos if (xfd >= 0) {
341 1.1 christos logopt = 0;
342 1.1 christos if (ioctl(xfd, SIOCGETLG, &logopt))
343 1.1 christos ipferror(xfd, "ioctl(SIOCGETLG)");
344 1.1 christos else {
345 1.1 christos logopt = 1 - logopt;
346 1.1 christos if (ioctl(xfd, SIOCSETLG, &logopt))
347 1.1 christos ipferror(xfd, "ioctl(SIOCSETLG)");
348 1.1 christos }
349 1.1 christos close(xfd);
350 1.1 christos }
351 1.1 christos }
352 1.1 christos }
353 1.1 christos
354 1.1 christos
355 1.1 christos static void flushfilter(arg, filter)
356 1.1 christos char *arg;
357 1.1 christos int *filter;
358 1.1 christos {
359 1.1 christos int fl = 0, rem;
360 1.1 christos
361 1.1 christos if (!arg || !*arg)
362 1.1 christos return;
363 1.1 christos if (!strcmp(arg, "s") || !strcmp(arg, "S") || ISDIGIT(*arg)) {
364 1.1 christos if (*arg == 'S')
365 1.1 christos fl = 0;
366 1.1 christos else if (*arg == 's')
367 1.1 christos fl = 1;
368 1.1 christos else
369 1.1 christos fl = atoi(arg);
370 1.1 christos rem = fl;
371 1.1 christos
372 1.1 christos closedevice();
373 1.1 christos if (opendevice(IPSTATE_NAME, 1) == -2)
374 1.1 christos exit(1);
375 1.1 christos
376 1.1 christos if (!(opts & OPT_DONOTHING)) {
377 1.1 christos if (use_inet6) {
378 1.1 christos fprintf(stderr,
379 1.1 christos "IPv6 rules are no longer seperate\n");
380 1.1 christos } else if (filter != NULL) {
381 1.1 christos ipfobj_t obj;
382 1.1 christos
383 1.1 christos obj.ipfo_rev = IPFILTER_VERSION;
384 1.1 christos obj.ipfo_size = filter[0] * sizeof(int);
385 1.1 christos obj.ipfo_type = IPFOBJ_IPFEXPR;
386 1.1 christos obj.ipfo_ptr = filter;
387 1.1 christos if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) {
388 1.1 christos ipferror(fd, "ioctl(SIOCMATCHFLUSH)");
389 1.1 christos fl = -1;
390 1.1 christos } else {
391 1.1 christos fl = obj.ipfo_retval;
392 1.1 christos }
393 1.1 christos } else {
394 1.1 christos if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
395 1.1 christos ipferror(fd, "ioctl(SIOCIPFFL)");
396 1.1 christos exit(1);
397 1.1 christos }
398 1.1 christos }
399 1.1 christos }
400 1.1 christos if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) {
401 1.1 christos printf("remove flags %s (%d)\n", arg, rem);
402 1.1 christos }
403 1.1 christos if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
404 1.1 christos printf("%d state entries removed\n", fl);
405 1.1 christos }
406 1.1 christos closedevice();
407 1.1 christos return;
408 1.1 christos }
409 1.1 christos
410 1.1 christos #ifdef SIOCIPFFA
411 1.1 christos if (!strcmp(arg, "u")) {
412 1.1 christos closedevice();
413 1.1 christos /*
414 1.1 christos * Flush auth rules and packets
415 1.1 christos */
416 1.1 christos if (opendevice(IPL_AUTH, 1) == -1)
417 1.1 christos perror("open(IPL_AUTH)");
418 1.1 christos else {
419 1.1 christos if (ioctl(fd, SIOCIPFFA, &fl) == -1)
420 1.1 christos ipferror(fd, "ioctl(SIOCIPFFA)");
421 1.1 christos }
422 1.1 christos closedevice();
423 1.1 christos return;
424 1.1 christos }
425 1.1 christos #endif
426 1.1 christos
427 1.1 christos if (strchr(arg, 'i') || strchr(arg, 'I'))
428 1.1 christos fl = FR_INQUE;
429 1.1 christos if (strchr(arg, 'o') || strchr(arg, 'O'))
430 1.1 christos fl = FR_OUTQUE;
431 1.1 christos if (strchr(arg, 'a') || strchr(arg, 'A'))
432 1.1 christos fl = FR_OUTQUE|FR_INQUE;
433 1.1 christos if (opts & OPT_INACTIVE)
434 1.1 christos fl |= FR_INACTIVE;
435 1.1 christos rem = fl;
436 1.1 christos
437 1.1 christos if (opendevice(ipfname, 1) == -2)
438 1.1 christos exit(1);
439 1.1 christos
440 1.1 christos if (!(opts & OPT_DONOTHING)) {
441 1.1 christos if (use_inet6) {
442 1.1 christos if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
443 1.1 christos ipferror(fd, "ioctl(SIOCIPFL6)");
444 1.1 christos exit(1);
445 1.1 christos }
446 1.1 christos } else {
447 1.1 christos if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
448 1.1 christos ipferror(fd, "ioctl(SIOCIPFFL)");
449 1.1 christos exit(1);
450 1.1 christos }
451 1.1 christos }
452 1.1 christos }
453 1.1 christos
454 1.1 christos if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) {
455 1.1 christos printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "",
456 1.1 christos (rem & FR_OUTQUE) ? "O" : "", rem);
457 1.1 christos }
458 1.1 christos if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
459 1.1 christos printf("%d filter rules removed\n", fl);
460 1.1 christos }
461 1.1 christos return;
462 1.1 christos }
463 1.1 christos
464 1.1 christos
465 1.1 christos static void swapactive()
466 1.1 christos {
467 1.1 christos int in = 2;
468 1.1 christos
469 1.1 christos if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
470 1.1 christos ipferror(fd, "ioctl(SIOCSWAPA)");
471 1.1 christos else
472 1.1 christos printf("Set %d now inactive\n", in);
473 1.1 christos }
474 1.1 christos
475 1.1 christos
476 1.1 christos void ipf_frsync()
477 1.1 christos {
478 1.1 christos int frsyn = 0;
479 1.1 christos
480 1.1 christos if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1)
481 1.1 christos ipferror(fd, "SIOCFRSYN");
482 1.1 christos else
483 1.1 christos printf("filter sync'd\n");
484 1.1 christos }
485 1.1 christos
486 1.1 christos
487 1.1 christos void zerostats()
488 1.1 christos {
489 1.1 christos ipfobj_t obj;
490 1.1 christos friostat_t fio;
491 1.1 christos
492 1.1 christos obj.ipfo_rev = IPFILTER_VERSION;
493 1.1 christos obj.ipfo_type = IPFOBJ_IPFSTAT;
494 1.1 christos obj.ipfo_size = sizeof(fio);
495 1.1 christos obj.ipfo_ptr = &fio;
496 1.1 christos obj.ipfo_offset = 0;
497 1.1 christos
498 1.1 christos if (opendevice(ipfname, 1) != -2) {
499 1.1 christos if (ioctl(fd, SIOCFRZST, &obj) == -1) {
500 1.1 christos ipferror(fd, "ioctl(SIOCFRZST)");
501 1.1 christos exit(-1);
502 1.1 christos }
503 1.1 christos showstats(&fio);
504 1.1 christos }
505 1.1 christos
506 1.1 christos }
507 1.1 christos
508 1.1 christos
509 1.1 christos /*
510 1.1 christos * read the kernel stats for packets blocked and passed
511 1.1 christos */
512 1.1 christos static void showstats(fp)
513 1.1 christos friostat_t *fp;
514 1.1 christos {
515 1.1 christos printf("bad packets:\t\tin %lu\tout %lu\n",
516 1.1 christos fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
517 1.1 christos printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
518 1.1 christos fp->f_st[0].fr_block, fp->f_st[0].fr_pass,
519 1.1 christos fp->f_st[0].fr_nom);
520 1.1 christos printf(" counted %lu\n", fp->f_st[0].fr_acct);
521 1.1 christos printf("output packets:\t\tblocked %lu passed %lu nomatch %lu",
522 1.1 christos fp->f_st[1].fr_block, fp->f_st[1].fr_pass,
523 1.1 christos fp->f_st[1].fr_nom);
524 1.1 christos printf(" counted %lu\n", fp->f_st[0].fr_acct);
525 1.1 christos printf(" input packets logged:\tblocked %lu passed %lu\n",
526 1.1 christos fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl);
527 1.1 christos printf("output packets logged:\tblocked %lu passed %lu\n",
528 1.1 christos fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl);
529 1.1 christos }
530 1.1 christos
531 1.1 christos
532 1.1 christos static int showversion()
533 1.1 christos {
534 1.1 christos struct friostat fio;
535 1.1 christos ipfobj_t ipfo;
536 1.1 christos u_32_t flags;
537 1.1 christos char *s;
538 1.1 christos int vfd;
539 1.1 christos
540 1.1 christos bzero((caddr_t)&ipfo, sizeof(ipfo));
541 1.1 christos ipfo.ipfo_rev = IPFILTER_VERSION;
542 1.1 christos ipfo.ipfo_size = sizeof(fio);
543 1.1 christos ipfo.ipfo_ptr = (void *)&fio;
544 1.1 christos ipfo.ipfo_type = IPFOBJ_IPFSTAT;
545 1.1 christos
546 1.1 christos printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
547 1.1 christos
548 1.1 christos if ((vfd = open(ipfname, O_RDONLY)) == -1) {
549 1.1 christos perror("open device");
550 1.1 christos return 1;
551 1.1 christos }
552 1.1 christos
553 1.1 christos if (ioctl(vfd, SIOCGETFS, &ipfo)) {
554 1.1 christos ipferror(vfd, "ioctl(SIOCGETFS)");
555 1.1 christos close(vfd);
556 1.1 christos return 1;
557 1.1 christos }
558 1.1 christos close(vfd);
559 1.1 christos flags = get_flags();
560 1.1 christos
561 1.1 christos printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
562 1.1 christos (int)sizeof(fio.f_version), fio.f_version);
563 1.1 christos printf("Running: %s\n", (fio.f_running > 0) ? "yes" : "no");
564 1.1 christos printf("Log Flags: %#x = ", flags);
565 1.1 christos s = "";
566 1.1 christos if (flags & FF_LOGPASS) {
567 1.1 christos printf("pass");
568 1.1 christos s = ", ";
569 1.1 christos }
570 1.1 christos if (flags & FF_LOGBLOCK) {
571 1.1 christos printf("%sblock", s);
572 1.1 christos s = ", ";
573 1.1 christos }
574 1.1 christos if (flags & FF_LOGNOMATCH) {
575 1.1 christos printf("%snomatch", s);
576 1.1 christos s = ", ";
577 1.1 christos }
578 1.1 christos if (flags & FF_BLOCKNONIP) {
579 1.1 christos printf("%snonip", s);
580 1.1 christos s = ", ";
581 1.1 christos }
582 1.1 christos if (!*s)
583 1.1 christos printf("none set");
584 1.1 christos putchar('\n');
585 1.1 christos
586 1.1 christos printf("Default: ");
587 1.1 christos if (FR_ISPASS(fio.f_defpass))
588 1.1 christos s = "pass";
589 1.1 christos else if (FR_ISBLOCK(fio.f_defpass))
590 1.1 christos s = "block";
591 1.1 christos else
592 1.1 christos s = "nomatch -> block";
593 1.1 christos printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un");
594 1.1 christos printf("Active list: %d\n", fio.f_active);
595 1.1 christos printf("Feature mask: %#x\n", fio.f_features);
596 1.1 christos
597 1.1 christos return 0;
598 1.1 christos }
599