4 * Copyright (C) 2001-2006 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
9 # ifndef __FreeBSD_cc_version
10 # include <osreldate.h>
12 # if __FreeBSD_cc_version < 430000
13 # include <osreldate.h>
19 #include <sys/ioctl.h>
20 #include "netinet/ipl.h"
23 static const char sccsid
[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
24 static const char rcsid
[] = "@(#)Id: ipf.c,v 1.35.2.8 2007/05/10 06:12:01 darrenr Exp";
27 #if !defined(__SVR4) && defined(__GNUC__)
28 extern char *index
__P((const char *, int));
33 extern frentry_t
*frtop
;
36 void ipf_frsync
__P((void));
37 void zerostats
__P((void));
38 int main
__P((int, char *[]));
44 static void procfile
__P((char *, char *)), flushfilter
__P((char *));
45 static void set_state
__P((u_int
)), showstats
__P((friostat_t
*));
46 static void packetlogon
__P((char *)), swapactive
__P((void));
47 static int opendevice
__P((char *, int));
48 static void closedevice
__P((void));
49 static char *ipfname
= IPL_NAME
;
50 static void usage
__P((void));
51 static int showversion
__P((void));
52 static int get_flags
__P((void));
53 static void ipf_interceptadd
__P((int, ioctlfunc_t
, void *));
56 static ioctlfunc_t iocfunctions
[IPL_LOGSIZE
] = { ioctl
, ioctl
, ioctl
,
63 fprintf(stderr
, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n",
64 "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]",
65 "[-f filename] [-T <tuneopts>]");
79 while ((c
= getopt(argc
, argv
, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) {
91 opts
&= ~OPT_INACTIVE
;
94 if (strcmp(optarg
, "c") == 0)
107 procfile(argv
[0], optarg
);
113 opts
^= OPT_INACTIVE
;
119 opts
^= OPT_DONOTHING
;
124 ipfname
= IPAUTH_NAME
;
127 opts
^= OPT_NORESOLVE
;
136 if (opendevice(ipfname
, 1) >= 0)
137 ipf_dotuning(fd
, optarg
, ioctl
);
150 opts
^= OPT_ZERORULEST
;
169 static int opendevice(ipfdev
, check
)
173 if (opts
& OPT_DONOTHING
)
176 if (check
&& checkrev(ipfname
) == -1) {
177 fprintf(stderr
, "User/kernel version check failed\n");
185 if ((fd
= open(ipfdev
, O_RDWR
)) == -1)
186 if ((fd
= open(ipfdev
, O_RDONLY
)) == -1)
187 perror("open device");
192 static void closedevice()
199 static int get_flags()
203 if ((opendevice(ipfname
, 1) != -2) &&
204 (ioctl(fd
, SIOCGETFF
, &i
) == -1)) {
212 static void set_state(enable
)
215 if (opendevice(ipfname
, 0) != -2)
216 if (ioctl(fd
, SIOCFRENB
, &enable
) == -1) {
219 "IP FIlter: already initialized\n");
227 static void procfile(name
, file
)
230 (void) opendevice(ipfname
, 1);
234 ipf_parsefile(fd
, ipf_interceptadd
, iocfunctions
, file
);
239 emit(-1, -1, NULL
, NULL
);
244 static void ipf_interceptadd(fd
, ioctlfunc
, ptr
)
246 ioctlfunc_t ioctlfunc
;
252 ipf_addrule(fd
, ioctlfunc
, ptr
);
256 static void packetlogon(opt
)
259 int flag
, xfd
, logopt
, change
= 0;
263 if ((opts
& (OPT_DONOTHING
|OPT_VERBOSE
)) == OPT_VERBOSE
)
264 printf("log flag is currently %#x\n", flag
);
267 flag
&= ~(FF_LOGPASS
|FF_LOGNOMATCH
|FF_LOGBLOCK
);
269 if (strstr(opt
, "pass")) {
271 if (opts
& OPT_VERBOSE
)
272 printf("set log flag: pass\n");
275 if (strstr(opt
, "nomatch")) {
276 flag
|= FF_LOGNOMATCH
;
277 if (opts
& OPT_VERBOSE
)
278 printf("set log flag: nomatch\n");
281 if (strstr(opt
, "block") || index(opt
, 'd')) {
283 if (opts
& OPT_VERBOSE
)
284 printf("set log flag: block\n");
287 if (strstr(opt
, "none")) {
288 if (opts
& OPT_VERBOSE
)
289 printf("disable all log flags\n");
294 if (opendevice(ipfname
, 1) != -2 &&
295 (ioctl(fd
, SIOCSETFF
, &flag
) != 0))
296 perror("ioctl(SIOCSETFF)");
299 if ((opts
& (OPT_DONOTHING
|OPT_VERBOSE
)) == OPT_VERBOSE
) {
301 printf("log flags are now %#x\n", flag
);
304 if (strstr(opt
, "state")) {
305 if (opts
& OPT_VERBOSE
)
306 printf("set state log flag\n");
307 xfd
= open(IPSTATE_NAME
, O_RDWR
);
310 if (ioctl(xfd
, SIOCGETLG
, &logopt
))
311 perror("ioctl(SIOCGETLG)");
314 if (ioctl(xfd
, SIOCSETLG
, &logopt
))
315 perror("ioctl(SIOCSETLG)");
321 if (strstr(opt
, "nat")) {
322 if (opts
& OPT_VERBOSE
)
323 printf("set nat log flag\n");
324 xfd
= open(IPNAT_NAME
, O_RDWR
);
327 if (ioctl(xfd
, SIOCGETLG
, &logopt
))
328 perror("ioctl(SIOCGETLG)");
331 if (ioctl(xfd
, SIOCSETLG
, &logopt
))
332 perror("ioctl(SIOCSETLG)");
340 static void flushfilter(arg
)
347 if (!strcmp(arg
, "s") || !strcmp(arg
, "S") || ISDIGIT(*arg
)) {
350 else if (*arg
== 's')
357 if (opendevice(IPSTATE_NAME
, 1) == -2)
360 if (!(opts
& OPT_DONOTHING
)) {
362 if (ioctl(fd
, SIOCIPFL6
, &fl
) == -1) {
363 perror("ioctl(SIOCIPFL6)");
367 if (ioctl(fd
, SIOCIPFFL
, &fl
) == -1) {
368 perror("ioctl(SIOCIPFFL)");
373 if ((opts
& (OPT_DONOTHING
|OPT_VERBOSE
)) == OPT_VERBOSE
) {
374 printf("remove flags %s (%d)\n", arg
, rem
);
375 printf("removed %d entries\n", fl
);
382 if (!strcmp(arg
, "u")) {
385 * Flush auth rules and packets
387 if (opendevice(IPL_AUTH
, 1) == -1)
388 perror("open(IPL_AUTH)");
390 if (ioctl(fd
, SIOCIPFFA
, &fl
) == -1)
391 perror("ioctl(SIOCIPFFA)");
398 if (strchr(arg
, 'i') || strchr(arg
, 'I'))
400 if (strchr(arg
, 'o') || strchr(arg
, 'O'))
402 if (strchr(arg
, 'a') || strchr(arg
, 'A'))
403 fl
= FR_OUTQUE
|FR_INQUE
;
404 if (opts
& OPT_INACTIVE
)
408 if (opendevice(ipfname
, 1) == -2)
411 if (!(opts
& OPT_DONOTHING
)) {
413 if (ioctl(fd
, SIOCIPFL6
, &fl
) == -1) {
414 perror("ioctl(SIOCIPFL6)");
418 if (ioctl(fd
, SIOCIPFFL
, &fl
) == -1) {
419 perror("ioctl(SIOCIPFFL)");
425 if ((opts
& (OPT_DONOTHING
|OPT_VERBOSE
)) == OPT_VERBOSE
) {
426 printf("remove flags %s%s (%d)\n", (rem
& FR_INQUE
) ? "I" : "",
427 (rem
& FR_OUTQUE
) ? "O" : "", rem
);
428 printf("removed %d filter rules\n", fl
);
434 static void swapactive()
438 if (opendevice(ipfname
, 1) != -2 && ioctl(fd
, SIOCSWAPA
, &in
) == -1)
439 perror("ioctl(SIOCSWAPA)");
441 printf("Set %d now inactive\n", in
);
449 if (opendevice(ipfname
, 1) != -2 && ioctl(fd
, SIOCFRSYN
, &frsyn
) == -1)
452 printf("filter sync'd\n");
461 obj
.ipfo_rev
= IPFILTER_VERSION
;
462 obj
.ipfo_type
= IPFOBJ_IPFSTAT
;
463 obj
.ipfo_size
= sizeof(fio
);
467 if (opendevice(ipfname
, 1) != -2) {
468 if (ioctl(fd
, SIOCFRZST
, &obj
) == -1) {
469 perror("ioctl(SIOCFRZST)");
479 * read the kernel stats for packets blocked and passed
481 static void showstats(fp
)
484 printf("bad packets:\t\tin %lu\tout %lu\n",
485 fp
->f_st
[0].fr_bad
, fp
->f_st
[1].fr_bad
);
486 printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
487 fp
->f_st
[0].fr_block
, fp
->f_st
[0].fr_pass
,
489 printf(" counted %lu\n", fp
->f_st
[0].fr_acct
);
490 printf("output packets:\t\tblocked %lu passed %lu nomatch %lu",
491 fp
->f_st
[1].fr_block
, fp
->f_st
[1].fr_pass
,
493 printf(" counted %lu\n", fp
->f_st
[0].fr_acct
);
494 printf(" input packets logged:\tblocked %lu passed %lu\n",
495 fp
->f_st
[0].fr_bpkl
, fp
->f_st
[0].fr_ppkl
);
496 printf("output packets logged:\tblocked %lu passed %lu\n",
497 fp
->f_st
[1].fr_bpkl
, fp
->f_st
[1].fr_ppkl
);
498 printf(" packets logged:\tinput %lu-%lu output %lu-%lu\n",
499 fp
->f_st
[0].fr_pkl
, fp
->f_st
[0].fr_skip
,
500 fp
->f_st
[1].fr_pkl
, fp
->f_st
[1].fr_skip
);
504 static int showversion()
512 bzero((caddr_t
)&ipfo
, sizeof(ipfo
));
513 ipfo
.ipfo_rev
= IPFILTER_VERSION
;
514 ipfo
.ipfo_size
= sizeof(fio
);
515 ipfo
.ipfo_ptr
= (void *)&fio
;
516 ipfo
.ipfo_type
= IPFOBJ_IPFSTAT
;
518 printf("ipf: %s (%d)\n", IPL_VERSION
, (int)sizeof(frentry_t
));
520 if ((vfd
= open(ipfname
, O_RDONLY
)) == -1) {
521 perror("open device");
525 if (ioctl(vfd
, SIOCGETFS
, &ipfo
)) {
526 perror("ioctl(SIOCGETFS)");
533 printf("Kernel: %-*.*s\n", (int)sizeof(fio
.f_version
),
534 (int)sizeof(fio
.f_version
), fio
.f_version
);
535 printf("Running: %s\n", (fio
.f_running
> 0) ? "yes" : "no");
536 printf("Log Flags: %#x = ", flags
);
538 if (flags
& FF_LOGPASS
) {
542 if (flags
& FF_LOGBLOCK
) {
543 printf("%sblock", s
);
546 if (flags
& FF_LOGNOMATCH
) {
547 printf("%snomatch", s
);
550 if (flags
& FF_BLOCKNONIP
) {
551 printf("%snonip", s
);
559 if (FR_ISPASS(fio
.f_defpass
))
561 else if (FR_ISBLOCK(fio
.f_defpass
))
564 s
= "nomatch -> block";
565 printf("%s all, Logging: %savailable\n", s
, fio
.f_logging
? "" : "un");
566 printf("Active list: %d\n", fio
.f_active
);
567 printf("Feature mask: %#x\n", fio
.f_features
);