1145519Sdarrenr/*	$FreeBSD: stable/10/contrib/ipfilter/tools/ipf.c 313461 2017-02-09 02:08:42Z cy $	*/
2145510Sdarrenr
3145510Sdarrenr/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5145510Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
7145510Sdarrenr */
8145510Sdarrenr#ifdef	__FreeBSD__
9145510Sdarrenr# ifndef __FreeBSD_cc_version
10145510Sdarrenr#  include <osreldate.h>
11145510Sdarrenr# else
12145510Sdarrenr#  if __FreeBSD_cc_version < 430000
13145510Sdarrenr#   include <osreldate.h>
14145510Sdarrenr#  endif
15145510Sdarrenr# endif
16145510Sdarrenr#endif
17145510Sdarrenr#include "ipf.h"
18145510Sdarrenr#include <fcntl.h>
19255332Scy#include <ctype.h>
20145510Sdarrenr#include <sys/ioctl.h>
21145510Sdarrenr#include "netinet/ipl.h"
22145510Sdarrenr
23145510Sdarrenr#if !defined(lint)
24145510Sdarrenrstatic const char sccsid[] = "@(#)ipf.c	1.23 6/5/96 (C) 1993-2000 Darren Reed";
25255332Scystatic const char rcsid[] = "@(#)$Id$";
26145510Sdarrenr#endif
27145510Sdarrenr
28145510Sdarrenr#if !defined(__SVR4) && defined(__GNUC__)
29145510Sdarrenrextern	char	*index __P((const char *, int));
30145510Sdarrenr#endif
31145510Sdarrenr
32145510Sdarrenrextern	char	*optarg;
33145510Sdarrenrextern	int	optind;
34145510Sdarrenrextern	frentry_t *frtop;
35145510Sdarrenr
36145510Sdarrenr
37145510Sdarrenrvoid	ipf_frsync __P((void));
38145510Sdarrenrvoid	zerostats __P((void));
39145510Sdarrenrint	main __P((int, char *[]));
40145510Sdarrenr
41145510Sdarrenrint	opts = 0;
42145510Sdarrenrint	outputc = 0;
43145510Sdarrenrint	use_inet6 = 0;
44255332Scyint	exitstatus = 0;
45145510Sdarrenr
46255332Scystatic	void	procfile __P((char *));
47255332Scystatic	void	flushfilter __P((char *, int *));
48255332Scystatic	void	set_state __P((u_int));
49255332Scystatic	void	showstats __P((friostat_t *));
50255332Scystatic	void	packetlogon __P((char *));
51255332Scystatic	void	swapactive __P((void));
52145510Sdarrenrstatic	int	opendevice __P((char *, int));
53145510Sdarrenrstatic	void	closedevice __P((void));
54145510Sdarrenrstatic	char	*ipfname = IPL_NAME;
55145510Sdarrenrstatic	void	usage __P((void));
56145510Sdarrenrstatic	int	showversion __P((void));
57145510Sdarrenrstatic	int	get_flags __P((void));
58255332Scystatic	int	ipf_interceptadd __P((int, ioctlfunc_t, void *));
59145510Sdarrenr
60145510Sdarrenrstatic	int	fd = -1;
61145510Sdarrenrstatic	ioctlfunc_t	iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
62145510Sdarrenr						      ioctl, ioctl, ioctl,
63145510Sdarrenr						      ioctl, ioctl };
64145510Sdarrenr
65255332Scy/* XXX	The following was added to satisfy a rescue/rescue/ build
66255332Scy   XXX	requirement.  */
67255332Scyint	nohdrfields;
68145510Sdarrenr
69145510Sdarrenrstatic void usage()
70145510Sdarrenr{
71145510Sdarrenr	fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n",
72145510Sdarrenr		"[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]",
73145510Sdarrenr		"[-f filename] [-T <tuneopts>]");
74145510Sdarrenr	exit(1);
75145510Sdarrenr}
76145510Sdarrenr
77145510Sdarrenr
78145510Sdarrenrint main(argc,argv)
79255332Scy	int argc;
80255332Scy	char *argv[];
81145510Sdarrenr{
82255332Scy	int c, *filter = NULL;
83145510Sdarrenr
84145510Sdarrenr	if (argc < 2)
85145510Sdarrenr		usage();
86145510Sdarrenr
87255332Scy	assigndefined(getenv("IPF_PREDEFINED"));
88255332Scy
89255332Scy	while ((c = getopt(argc, argv, "46Ac:dDEf:F:Il:m:noPrRsT:vVyzZ")) != -1) {
90145510Sdarrenr		switch (c)
91145510Sdarrenr		{
92145510Sdarrenr		case '?' :
93145510Sdarrenr			usage();
94145510Sdarrenr			break;
95255332Scy		case '4' :
96255332Scy			use_inet6 = -1;
97255332Scy			break;
98145510Sdarrenr		case '6' :
99145510Sdarrenr			use_inet6 = 1;
100145510Sdarrenr			break;
101145510Sdarrenr		case 'A' :
102145510Sdarrenr			opts &= ~OPT_INACTIVE;
103145510Sdarrenr			break;
104145510Sdarrenr		case 'c' :
105145510Sdarrenr			if (strcmp(optarg, "c") == 0)
106145510Sdarrenr				outputc = 1;
107145510Sdarrenr			break;
108145510Sdarrenr		case 'E' :
109145510Sdarrenr			set_state((u_int)1);
110145510Sdarrenr			break;
111145510Sdarrenr		case 'D' :
112145510Sdarrenr			set_state((u_int)0);
113145510Sdarrenr			break;
114145510Sdarrenr		case 'd' :
115145510Sdarrenr			opts ^= OPT_DEBUG;
116145510Sdarrenr			break;
117145510Sdarrenr		case 'f' :
118255332Scy			procfile(optarg);
119145510Sdarrenr			break;
120145510Sdarrenr		case 'F' :
121255332Scy			flushfilter(optarg, filter);
122145510Sdarrenr			break;
123145510Sdarrenr		case 'I' :
124145510Sdarrenr			opts ^= OPT_INACTIVE;
125145510Sdarrenr			break;
126145510Sdarrenr		case 'l' :
127145510Sdarrenr			packetlogon(optarg);
128145510Sdarrenr			break;
129255332Scy		case 'm' :
130255332Scy			filter = parseipfexpr(optarg, NULL);
131255332Scy			break;
132145510Sdarrenr		case 'n' :
133255332Scy			opts ^= OPT_DONOTHING|OPT_DONTOPEN;
134145510Sdarrenr			break;
135145510Sdarrenr		case 'o' :
136145510Sdarrenr			break;
137145510Sdarrenr		case 'P' :
138145510Sdarrenr			ipfname = IPAUTH_NAME;
139145510Sdarrenr			break;
140145510Sdarrenr		case 'R' :
141145510Sdarrenr			opts ^= OPT_NORESOLVE;
142145510Sdarrenr			break;
143145510Sdarrenr		case 'r' :
144145510Sdarrenr			opts ^= OPT_REMOVE;
145145510Sdarrenr			break;
146145510Sdarrenr		case 's' :
147145510Sdarrenr			swapactive();
148145510Sdarrenr			break;
149145510Sdarrenr		case 'T' :
150145510Sdarrenr			if (opendevice(ipfname, 1) >= 0)
151145510Sdarrenr				ipf_dotuning(fd, optarg, ioctl);
152145510Sdarrenr			break;
153145510Sdarrenr		case 'v' :
154145510Sdarrenr			opts += OPT_VERBOSE;
155145510Sdarrenr			break;
156145510Sdarrenr		case 'V' :
157145510Sdarrenr			if (showversion())
158145510Sdarrenr				exit(1);
159145510Sdarrenr			break;
160145510Sdarrenr		case 'y' :
161145510Sdarrenr			ipf_frsync();
162145510Sdarrenr			break;
163145510Sdarrenr		case 'z' :
164145510Sdarrenr			opts ^= OPT_ZERORULEST;
165145510Sdarrenr			break;
166145510Sdarrenr		case 'Z' :
167145510Sdarrenr			zerostats();
168145510Sdarrenr			break;
169145510Sdarrenr		}
170145510Sdarrenr	}
171145510Sdarrenr
172145510Sdarrenr	if (optind < 2)
173145510Sdarrenr		usage();
174145510Sdarrenr
175145510Sdarrenr	if (fd != -1)
176145510Sdarrenr		(void) close(fd);
177145510Sdarrenr
178255332Scy	return(exitstatus);
179145510Sdarrenr	/* NOTREACHED */
180145510Sdarrenr}
181145510Sdarrenr
182145510Sdarrenr
183145510Sdarrenrstatic int opendevice(ipfdev, check)
184255332Scy	char *ipfdev;
185255332Scy	int check;
186145510Sdarrenr{
187145510Sdarrenr	if (opts & OPT_DONOTHING)
188145510Sdarrenr		return -2;
189145510Sdarrenr
190145510Sdarrenr	if (check && checkrev(ipfname) == -1) {
191145510Sdarrenr		fprintf(stderr, "User/kernel version check failed\n");
192145510Sdarrenr		return -2;
193145510Sdarrenr	}
194145510Sdarrenr
195145510Sdarrenr	if (!ipfdev)
196145510Sdarrenr		ipfdev = ipfname;
197145510Sdarrenr
198145510Sdarrenr	if (fd == -1)
199145510Sdarrenr		if ((fd = open(ipfdev, O_RDWR)) == -1)
200145510Sdarrenr			if ((fd = open(ipfdev, O_RDONLY)) == -1)
201255332Scy				ipferror(fd, "open device");
202145510Sdarrenr	return fd;
203145510Sdarrenr}
204145510Sdarrenr
205145510Sdarrenr
206145510Sdarrenrstatic void closedevice()
207145510Sdarrenr{
208145510Sdarrenr	close(fd);
209145510Sdarrenr	fd = -1;
210145510Sdarrenr}
211145510Sdarrenr
212145510Sdarrenr
213145510Sdarrenrstatic	int	get_flags()
214145510Sdarrenr{
215161357Sguido	int i = 0;
216145510Sdarrenr
217145510Sdarrenr	if ((opendevice(ipfname, 1) != -2) &&
218145510Sdarrenr	    (ioctl(fd, SIOCGETFF, &i) == -1)) {
219255332Scy		ipferror(fd, "SIOCGETFF");
220145510Sdarrenr		return 0;
221145510Sdarrenr	}
222145510Sdarrenr	return i;
223145510Sdarrenr}
224145510Sdarrenr
225145510Sdarrenr
226145510Sdarrenrstatic	void	set_state(enable)
227255332Scy	u_int	enable;
228145510Sdarrenr{
229255332Scy	if (opendevice(ipfname, 0) != -2) {
230145510Sdarrenr		if (ioctl(fd, SIOCFRENB, &enable) == -1) {
231255332Scy			if (errno == EBUSY) {
232145510Sdarrenr				fprintf(stderr,
233145510Sdarrenr					"IP FIlter: already initialized\n");
234255332Scy			} else {
235255332Scy				ipferror(fd, "SIOCFRENB");
236255332Scy			}
237145510Sdarrenr		}
238255332Scy	}
239145510Sdarrenr	return;
240145510Sdarrenr}
241145510Sdarrenr
242145510Sdarrenr
243255332Scystatic	void	procfile(file)
244255332Scy	char	*file;
245145510Sdarrenr{
246145510Sdarrenr	(void) opendevice(ipfname, 1);
247145510Sdarrenr
248145510Sdarrenr	initparse();
249145510Sdarrenr
250145510Sdarrenr	ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file);
251145510Sdarrenr
252145510Sdarrenr	if (outputc) {
253145510Sdarrenr		printC(0);
254145510Sdarrenr		printC(1);
255145510Sdarrenr		emit(-1, -1, NULL, NULL);
256145510Sdarrenr	}
257145510Sdarrenr}
258145510Sdarrenr
259145510Sdarrenr
260255332Scystatic int ipf_interceptadd(fd, ioctlfunc, ptr)
261255332Scy	int fd;
262255332Scy	ioctlfunc_t ioctlfunc;
263255332Scy	void *ptr;
264145510Sdarrenr{
265145510Sdarrenr	if (outputc)
266145510Sdarrenr		printc(ptr);
267145510Sdarrenr
268255332Scy	if (ipf_addrule(fd, ioctlfunc, ptr) != 0)
269255332Scy		exitstatus = 1;
270255332Scy	return 0;
271145510Sdarrenr}
272145510Sdarrenr
273145510Sdarrenr
274145510Sdarrenrstatic void packetlogon(opt)
275255332Scy	char	*opt;
276145510Sdarrenr{
277145510Sdarrenr	int	flag, xfd, logopt, change = 0;
278145510Sdarrenr
279145510Sdarrenr	flag = get_flags();
280145510Sdarrenr	if (flag != 0) {
281145510Sdarrenr		if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
282145510Sdarrenr			printf("log flag is currently %#x\n", flag);
283145510Sdarrenr	}
284145510Sdarrenr
285145510Sdarrenr	flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK);
286145510Sdarrenr
287145510Sdarrenr	if (strstr(opt, "pass")) {
288145510Sdarrenr		flag |= FF_LOGPASS;
289145510Sdarrenr		if (opts & OPT_VERBOSE)
290145510Sdarrenr			printf("set log flag: pass\n");
291145510Sdarrenr		change = 1;
292145510Sdarrenr	}
293145510Sdarrenr	if (strstr(opt, "nomatch")) {
294145510Sdarrenr		flag |= FF_LOGNOMATCH;
295145510Sdarrenr		if (opts & OPT_VERBOSE)
296145510Sdarrenr			printf("set log flag: nomatch\n");
297145510Sdarrenr		change = 1;
298145510Sdarrenr	}
299283748Semaste	if (strstr(opt, "block") || strchr(opt, 'd')) {
300145510Sdarrenr		flag |= FF_LOGBLOCK;
301145510Sdarrenr		if (opts & OPT_VERBOSE)
302145510Sdarrenr			printf("set log flag: block\n");
303145510Sdarrenr		change = 1;
304145510Sdarrenr	}
305145510Sdarrenr	if (strstr(opt, "none")) {
306145510Sdarrenr		if (opts & OPT_VERBOSE)
307145510Sdarrenr			printf("disable all log flags\n");
308145510Sdarrenr		change = 1;
309145510Sdarrenr	}
310145510Sdarrenr
311145510Sdarrenr	if (change == 1) {
312145510Sdarrenr		if (opendevice(ipfname, 1) != -2 &&
313145510Sdarrenr		    (ioctl(fd, SIOCSETFF, &flag) != 0))
314255332Scy			ipferror(fd, "ioctl(SIOCSETFF)");
315145510Sdarrenr	}
316145510Sdarrenr
317145510Sdarrenr	if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
318145510Sdarrenr		flag = get_flags();
319145510Sdarrenr		printf("log flags are now %#x\n", flag);
320145510Sdarrenr	}
321145510Sdarrenr
322145510Sdarrenr	if (strstr(opt, "state")) {
323145510Sdarrenr		if (opts & OPT_VERBOSE)
324145510Sdarrenr			printf("set state log flag\n");
325145510Sdarrenr		xfd = open(IPSTATE_NAME, O_RDWR);
326145510Sdarrenr		if (xfd >= 0) {
327145510Sdarrenr			logopt = 0;
328145510Sdarrenr			if (ioctl(xfd, SIOCGETLG, &logopt))
329255332Scy				ipferror(fd, "ioctl(SIOCGETLG)");
330145510Sdarrenr			else {
331145510Sdarrenr				logopt = 1 - logopt;
332145510Sdarrenr				if (ioctl(xfd, SIOCSETLG, &logopt))
333255332Scy					ipferror(xfd, "ioctl(SIOCSETLG)");
334145510Sdarrenr			}
335145510Sdarrenr			close(xfd);
336145510Sdarrenr		}
337145510Sdarrenr	}
338145510Sdarrenr
339145510Sdarrenr	if (strstr(opt, "nat")) {
340145510Sdarrenr		if (opts & OPT_VERBOSE)
341145510Sdarrenr			printf("set nat log flag\n");
342145510Sdarrenr		xfd = open(IPNAT_NAME, O_RDWR);
343145510Sdarrenr		if (xfd >= 0) {
344145510Sdarrenr			logopt = 0;
345145510Sdarrenr			if (ioctl(xfd, SIOCGETLG, &logopt))
346255332Scy				ipferror(xfd, "ioctl(SIOCGETLG)");
347145510Sdarrenr			else {
348145510Sdarrenr				logopt = 1 - logopt;
349145510Sdarrenr				if (ioctl(xfd, SIOCSETLG, &logopt))
350255332Scy					ipferror(xfd, "ioctl(SIOCSETLG)");
351145510Sdarrenr			}
352145510Sdarrenr			close(xfd);
353145510Sdarrenr		}
354145510Sdarrenr	}
355145510Sdarrenr}
356145510Sdarrenr
357145510Sdarrenr
358255332Scystatic void flushfilter(arg, filter)
359255332Scy	char *arg;
360255332Scy	int *filter;
361145510Sdarrenr{
362145510Sdarrenr	int	fl = 0, rem;
363145510Sdarrenr
364145510Sdarrenr	if (!arg || !*arg)
365145510Sdarrenr		return;
366170268Sdarrenr	if (!strcmp(arg, "s") || !strcmp(arg, "S") || ISDIGIT(*arg)) {
367145510Sdarrenr		if (*arg == 'S')
368145510Sdarrenr			fl = 0;
369170268Sdarrenr		else if (*arg == 's')
370170268Sdarrenr			fl = 1;
371145510Sdarrenr		else
372170268Sdarrenr			fl = atoi(arg);
373145510Sdarrenr		rem = fl;
374145510Sdarrenr
375145510Sdarrenr		closedevice();
376145510Sdarrenr		if (opendevice(IPSTATE_NAME, 1) == -2)
377145510Sdarrenr			exit(1);
378145510Sdarrenr
379145510Sdarrenr		if (!(opts & OPT_DONOTHING)) {
380145510Sdarrenr			if (use_inet6) {
381255332Scy				fprintf(stderr,
382255332Scy					"IPv6 rules are no longer seperate\n");
383255332Scy			} else if (filter != NULL) {
384255332Scy				ipfobj_t obj;
385255332Scy
386255332Scy				obj.ipfo_rev = IPFILTER_VERSION;
387255332Scy				obj.ipfo_size = filter[0] * sizeof(int);
388255332Scy				obj.ipfo_type = IPFOBJ_IPFEXPR;
389255332Scy				obj.ipfo_ptr = filter;
390255332Scy				if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) {
391255332Scy					ipferror(fd, "ioctl(SIOCMATCHFLUSH)");
392255332Scy					fl = -1;
393255332Scy				} else {
394255332Scy					fl = obj.ipfo_retval;
395145510Sdarrenr				}
396145510Sdarrenr			} else {
397145510Sdarrenr				if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
398255332Scy					ipferror(fd, "ioctl(SIOCIPFFL)");
399145510Sdarrenr					exit(1);
400145510Sdarrenr				}
401145510Sdarrenr			}
402145510Sdarrenr		}
403255332Scy		if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) {
404145510Sdarrenr			printf("remove flags %s (%d)\n", arg, rem);
405145510Sdarrenr		}
406255332Scy		if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
407255332Scy			printf("%d state entries removed\n", fl);
408255332Scy		}
409145510Sdarrenr		closedevice();
410145510Sdarrenr		return;
411313461Scy	} else if (strchr(arg, 'i') || strchr(arg, 'I'))
412145510Sdarrenr		fl = FR_INQUE;
413313441Scy	else if (strchr(arg, 'o') || strchr(arg, 'O'))
414145510Sdarrenr		fl = FR_OUTQUE;
415313441Scy	else if (strchr(arg, 'a') || strchr(arg, 'A'))
416145510Sdarrenr		fl = FR_OUTQUE|FR_INQUE;
417313441Scy	else {
418313441Scy		fprintf(stderr, "Incorrect flush argument: %s\n", arg);
419313441Scy		usage();
420313441Scy	}
421145510Sdarrenr	if (opts & OPT_INACTIVE)
422145510Sdarrenr		fl |= FR_INACTIVE;
423145510Sdarrenr	rem = fl;
424145510Sdarrenr
425145510Sdarrenr	if (opendevice(ipfname, 1) == -2)
426145510Sdarrenr		exit(1);
427145510Sdarrenr
428145510Sdarrenr	if (!(opts & OPT_DONOTHING)) {
429145510Sdarrenr		if (use_inet6) {
430145510Sdarrenr			if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
431255332Scy				ipferror(fd, "ioctl(SIOCIPFL6)");
432145510Sdarrenr				exit(1);
433145510Sdarrenr			}
434145510Sdarrenr		} else {
435145510Sdarrenr			if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
436255332Scy				ipferror(fd, "ioctl(SIOCIPFFL)");
437145510Sdarrenr				exit(1);
438145510Sdarrenr			}
439145510Sdarrenr		}
440145510Sdarrenr	}
441145510Sdarrenr
442255332Scy	if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) {
443145510Sdarrenr		printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "",
444145510Sdarrenr			(rem & FR_OUTQUE) ? "O" : "", rem);
445145510Sdarrenr	}
446255332Scy	if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
447255332Scy		printf("%d filter rules removed\n", fl);
448255332Scy	}
449145510Sdarrenr	return;
450145510Sdarrenr}
451145510Sdarrenr
452145510Sdarrenr
453145510Sdarrenrstatic void swapactive()
454145510Sdarrenr{
455145510Sdarrenr	int in = 2;
456145510Sdarrenr
457145510Sdarrenr	if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
458255332Scy		ipferror(fd, "ioctl(SIOCSWAPA)");
459145510Sdarrenr	else
460145510Sdarrenr		printf("Set %d now inactive\n", in);
461145510Sdarrenr}
462145510Sdarrenr
463145510Sdarrenr
464145510Sdarrenrvoid ipf_frsync()
465145510Sdarrenr{
466145510Sdarrenr	int frsyn = 0;
467145510Sdarrenr
468145510Sdarrenr	if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1)
469255332Scy		ipferror(fd, "SIOCFRSYN");
470145510Sdarrenr	else
471145510Sdarrenr		printf("filter sync'd\n");
472145510Sdarrenr}
473145510Sdarrenr
474145510Sdarrenr
475145510Sdarrenrvoid zerostats()
476145510Sdarrenr{
477157836Sdarrenr	ipfobj_t	obj;
478145510Sdarrenr	friostat_t	fio;
479145510Sdarrenr
480157836Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
481157836Sdarrenr	obj.ipfo_type = IPFOBJ_IPFSTAT;
482157836Sdarrenr	obj.ipfo_size = sizeof(fio);
483157836Sdarrenr	obj.ipfo_ptr = &fio;
484157836Sdarrenr	obj.ipfo_offset = 0;
485157836Sdarrenr
486145510Sdarrenr	if (opendevice(ipfname, 1) != -2) {
487157836Sdarrenr		if (ioctl(fd, SIOCFRZST, &obj) == -1) {
488255332Scy			ipferror(fd, "ioctl(SIOCFRZST)");
489145510Sdarrenr			exit(-1);
490145510Sdarrenr		}
491157836Sdarrenr		showstats(&fio);
492145510Sdarrenr	}
493145510Sdarrenr
494145510Sdarrenr}
495145510Sdarrenr
496145510Sdarrenr
497145510Sdarrenr/*
498145510Sdarrenr * read the kernel stats for packets blocked and passed
499145510Sdarrenr */
500145510Sdarrenrstatic void showstats(fp)
501255332Scy	friostat_t	*fp;
502145510Sdarrenr{
503145510Sdarrenr	printf("bad packets:\t\tin %lu\tout %lu\n",
504145510Sdarrenr			fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
505145510Sdarrenr	printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
506145510Sdarrenr			fp->f_st[0].fr_block, fp->f_st[0].fr_pass,
507145510Sdarrenr			fp->f_st[0].fr_nom);
508145510Sdarrenr	printf(" counted %lu\n", fp->f_st[0].fr_acct);
509145510Sdarrenr	printf("output packets:\t\tblocked %lu passed %lu nomatch %lu",
510145510Sdarrenr			fp->f_st[1].fr_block, fp->f_st[1].fr_pass,
511145510Sdarrenr			fp->f_st[1].fr_nom);
512145510Sdarrenr	printf(" counted %lu\n", fp->f_st[0].fr_acct);
513145510Sdarrenr	printf(" input packets logged:\tblocked %lu passed %lu\n",
514145510Sdarrenr			fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl);
515145510Sdarrenr	printf("output packets logged:\tblocked %lu passed %lu\n",
516145510Sdarrenr			fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl);
517145510Sdarrenr}
518145510Sdarrenr
519145510Sdarrenr
520145510Sdarrenrstatic int showversion()
521145510Sdarrenr{
522145510Sdarrenr	struct friostat fio;
523145510Sdarrenr	ipfobj_t ipfo;
524145510Sdarrenr	u_32_t flags;
525145510Sdarrenr	char *s;
526145510Sdarrenr	int vfd;
527145510Sdarrenr
528145510Sdarrenr	bzero((caddr_t)&ipfo, sizeof(ipfo));
529145510Sdarrenr	ipfo.ipfo_rev = IPFILTER_VERSION;
530145510Sdarrenr	ipfo.ipfo_size = sizeof(fio);
531145510Sdarrenr	ipfo.ipfo_ptr = (void *)&fio;
532145510Sdarrenr	ipfo.ipfo_type = IPFOBJ_IPFSTAT;
533145510Sdarrenr
534145510Sdarrenr	printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
535145510Sdarrenr
536145510Sdarrenr	if ((vfd = open(ipfname, O_RDONLY)) == -1) {
537145510Sdarrenr		perror("open device");
538145510Sdarrenr		return 1;
539145510Sdarrenr	}
540145510Sdarrenr
541145510Sdarrenr	if (ioctl(vfd, SIOCGETFS, &ipfo)) {
542255332Scy		ipferror(vfd, "ioctl(SIOCGETFS)");
543145510Sdarrenr		close(vfd);
544145510Sdarrenr		return 1;
545145510Sdarrenr	}
546145510Sdarrenr	close(vfd);
547145510Sdarrenr	flags = get_flags();
548145510Sdarrenr
549145510Sdarrenr	printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
550145510Sdarrenr		(int)sizeof(fio.f_version), fio.f_version);
551145510Sdarrenr	printf("Running: %s\n", (fio.f_running > 0) ? "yes" : "no");
552145510Sdarrenr	printf("Log Flags: %#x = ", flags);
553145510Sdarrenr	s = "";
554145510Sdarrenr	if (flags & FF_LOGPASS) {
555145510Sdarrenr		printf("pass");
556145510Sdarrenr		s = ", ";
557145510Sdarrenr	}
558145510Sdarrenr	if (flags & FF_LOGBLOCK) {
559145510Sdarrenr		printf("%sblock", s);
560145510Sdarrenr		s = ", ";
561145510Sdarrenr	}
562145510Sdarrenr	if (flags & FF_LOGNOMATCH) {
563145510Sdarrenr		printf("%snomatch", s);
564145510Sdarrenr		s = ", ";
565145510Sdarrenr	}
566145510Sdarrenr	if (flags & FF_BLOCKNONIP) {
567145510Sdarrenr		printf("%snonip", s);
568145510Sdarrenr		s = ", ";
569145510Sdarrenr	}
570145510Sdarrenr	if (!*s)
571145510Sdarrenr		printf("none set");
572145510Sdarrenr	putchar('\n');
573145510Sdarrenr
574145510Sdarrenr	printf("Default: ");
575145510Sdarrenr	if (FR_ISPASS(fio.f_defpass))
576145510Sdarrenr		s = "pass";
577145510Sdarrenr	else if (FR_ISBLOCK(fio.f_defpass))
578145510Sdarrenr		s = "block";
579145510Sdarrenr	else
580145510Sdarrenr		s = "nomatch -> block";
581145510Sdarrenr	printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un");
582145510Sdarrenr	printf("Active list: %d\n", fio.f_active);
583145510Sdarrenr	printf("Feature mask: %#x\n", fio.f_features);
584145510Sdarrenr
585145510Sdarrenr	return 0;
586145510Sdarrenr}
587