Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ipf / tools / ipf.c
blobe393f40a888931b692ed49317b37e02acf0d855f
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2001-2006 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8 #ifdef __FreeBSD__
9 # ifndef __FreeBSD_cc_version
10 # include <osreldate.h>
11 # else
12 # if __FreeBSD_cc_version < 430000
13 # include <osreldate.h>
14 # endif
15 # endif
16 #endif
17 #include "ipf.h"
18 #include <fcntl.h>
19 #include <sys/ioctl.h>
20 #include "netinet/ipl.h"
22 #if !defined(lint)
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";
25 #endif
27 #if !defined(__SVR4) && defined(__GNUC__)
28 extern char *index __P((const char *, int));
29 #endif
31 extern char *optarg;
32 extern int optind;
33 extern frentry_t *frtop;
36 void ipf_frsync __P((void));
37 void zerostats __P((void));
38 int main __P((int, char *[]));
40 int opts = 0;
41 int outputc = 0;
42 int use_inet6 = 0;
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 *));
55 static int fd = -1;
56 static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
57 ioctl, ioctl, ioctl,
58 ioctl, ioctl };
61 static void usage()
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>]");
66 exit(1);
70 int main(argc,argv)
71 int argc;
72 char *argv[];
74 int c;
76 if (argc < 2)
77 usage();
79 while ((c = getopt(argc, argv, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) {
80 switch (c)
82 case '?' :
83 usage();
84 break;
85 #ifdef USE_INET6
86 case '6' :
87 use_inet6 = 1;
88 break;
89 #endif
90 case 'A' :
91 opts &= ~OPT_INACTIVE;
92 break;
93 case 'c' :
94 if (strcmp(optarg, "c") == 0)
95 outputc = 1;
96 break;
97 case 'E' :
98 set_state((u_int)1);
99 break;
100 case 'D' :
101 set_state((u_int)0);
102 break;
103 case 'd' :
104 opts ^= OPT_DEBUG;
105 break;
106 case 'f' :
107 procfile(argv[0], optarg);
108 break;
109 case 'F' :
110 flushfilter(optarg);
111 break;
112 case 'I' :
113 opts ^= OPT_INACTIVE;
114 break;
115 case 'l' :
116 packetlogon(optarg);
117 break;
118 case 'n' :
119 opts ^= OPT_DONOTHING;
120 break;
121 case 'o' :
122 break;
123 case 'P' :
124 ipfname = IPAUTH_NAME;
125 break;
126 case 'R' :
127 opts ^= OPT_NORESOLVE;
128 break;
129 case 'r' :
130 opts ^= OPT_REMOVE;
131 break;
132 case 's' :
133 swapactive();
134 break;
135 case 'T' :
136 if (opendevice(ipfname, 1) >= 0)
137 ipf_dotuning(fd, optarg, ioctl);
138 break;
139 case 'v' :
140 opts += OPT_VERBOSE;
141 break;
142 case 'V' :
143 if (showversion())
144 exit(1);
145 break;
146 case 'y' :
147 ipf_frsync();
148 break;
149 case 'z' :
150 opts ^= OPT_ZERORULEST;
151 break;
152 case 'Z' :
153 zerostats();
154 break;
158 if (optind < 2)
159 usage();
161 if (fd != -1)
162 (void) close(fd);
164 return(0);
165 /* NOTREACHED */
169 static int opendevice(ipfdev, check)
170 char *ipfdev;
171 int check;
173 if (opts & OPT_DONOTHING)
174 return -2;
176 if (check && checkrev(ipfname) == -1) {
177 fprintf(stderr, "User/kernel version check failed\n");
178 return -2;
181 if (!ipfdev)
182 ipfdev = ipfname;
184 if (fd == -1)
185 if ((fd = open(ipfdev, O_RDWR)) == -1)
186 if ((fd = open(ipfdev, O_RDONLY)) == -1)
187 perror("open device");
188 return fd;
192 static void closedevice()
194 close(fd);
195 fd = -1;
199 static int get_flags()
201 int i = 0;
203 if ((opendevice(ipfname, 1) != -2) &&
204 (ioctl(fd, SIOCGETFF, &i) == -1)) {
205 perror("SIOCGETFF");
206 return 0;
208 return i;
212 static void set_state(enable)
213 u_int enable;
215 if (opendevice(ipfname, 0) != -2)
216 if (ioctl(fd, SIOCFRENB, &enable) == -1) {
217 if (errno == EBUSY)
218 fprintf(stderr,
219 "IP FIlter: already initialized\n");
220 else
221 perror("SIOCFRENB");
223 return;
227 static void procfile(name, file)
228 char *name, *file;
230 (void) opendevice(ipfname, 1);
232 initparse();
234 ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file);
236 if (outputc) {
237 printC(0);
238 printC(1);
239 emit(-1, -1, NULL, NULL);
244 static void ipf_interceptadd(fd, ioctlfunc, ptr)
245 int fd;
246 ioctlfunc_t ioctlfunc;
247 void *ptr;
249 if (outputc)
250 printc(ptr);
252 ipf_addrule(fd, ioctlfunc, ptr);
256 static void packetlogon(opt)
257 char *opt;
259 int flag, xfd, logopt, change = 0;
261 flag = get_flags();
262 if (flag != 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")) {
270 flag |= FF_LOGPASS;
271 if (opts & OPT_VERBOSE)
272 printf("set log flag: pass\n");
273 change = 1;
275 if (strstr(opt, "nomatch")) {
276 flag |= FF_LOGNOMATCH;
277 if (opts & OPT_VERBOSE)
278 printf("set log flag: nomatch\n");
279 change = 1;
281 if (strstr(opt, "block") || index(opt, 'd')) {
282 flag |= FF_LOGBLOCK;
283 if (opts & OPT_VERBOSE)
284 printf("set log flag: block\n");
285 change = 1;
287 if (strstr(opt, "none")) {
288 if (opts & OPT_VERBOSE)
289 printf("disable all log flags\n");
290 change = 1;
293 if (change == 1) {
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) {
300 flag = get_flags();
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);
308 if (xfd >= 0) {
309 logopt = 0;
310 if (ioctl(xfd, SIOCGETLG, &logopt))
311 perror("ioctl(SIOCGETLG)");
312 else {
313 logopt = 1 - logopt;
314 if (ioctl(xfd, SIOCSETLG, &logopt))
315 perror("ioctl(SIOCSETLG)");
317 close(xfd);
321 if (strstr(opt, "nat")) {
322 if (opts & OPT_VERBOSE)
323 printf("set nat log flag\n");
324 xfd = open(IPNAT_NAME, O_RDWR);
325 if (xfd >= 0) {
326 logopt = 0;
327 if (ioctl(xfd, SIOCGETLG, &logopt))
328 perror("ioctl(SIOCGETLG)");
329 else {
330 logopt = 1 - logopt;
331 if (ioctl(xfd, SIOCSETLG, &logopt))
332 perror("ioctl(SIOCSETLG)");
334 close(xfd);
340 static void flushfilter(arg)
341 char *arg;
343 int fl = 0, rem;
345 if (!arg || !*arg)
346 return;
347 if (!strcmp(arg, "s") || !strcmp(arg, "S") || ISDIGIT(*arg)) {
348 if (*arg == 'S')
349 fl = 0;
350 else if (*arg == 's')
351 fl = 1;
352 else
353 fl = atoi(arg);
354 rem = fl;
356 closedevice();
357 if (opendevice(IPSTATE_NAME, 1) == -2)
358 exit(1);
360 if (!(opts & OPT_DONOTHING)) {
361 if (use_inet6) {
362 if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
363 perror("ioctl(SIOCIPFL6)");
364 exit(1);
366 } else {
367 if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
368 perror("ioctl(SIOCIPFFL)");
369 exit(1);
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);
377 closedevice();
378 return;
381 #ifdef SIOCIPFFA
382 if (!strcmp(arg, "u")) {
383 closedevice();
385 * Flush auth rules and packets
387 if (opendevice(IPL_AUTH, 1) == -1)
388 perror("open(IPL_AUTH)");
389 else {
390 if (ioctl(fd, SIOCIPFFA, &fl) == -1)
391 perror("ioctl(SIOCIPFFA)");
393 closedevice();
394 return;
396 #endif
398 if (strchr(arg, 'i') || strchr(arg, 'I'))
399 fl = FR_INQUE;
400 if (strchr(arg, 'o') || strchr(arg, 'O'))
401 fl = FR_OUTQUE;
402 if (strchr(arg, 'a') || strchr(arg, 'A'))
403 fl = FR_OUTQUE|FR_INQUE;
404 if (opts & OPT_INACTIVE)
405 fl |= FR_INACTIVE;
406 rem = fl;
408 if (opendevice(ipfname, 1) == -2)
409 exit(1);
411 if (!(opts & OPT_DONOTHING)) {
412 if (use_inet6) {
413 if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
414 perror("ioctl(SIOCIPFL6)");
415 exit(1);
417 } else {
418 if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
419 perror("ioctl(SIOCIPFFL)");
420 exit(1);
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);
430 return;
434 static void swapactive()
436 int in = 2;
438 if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
439 perror("ioctl(SIOCSWAPA)");
440 else
441 printf("Set %d now inactive\n", in);
445 void ipf_frsync()
447 int frsyn = 0;
449 if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1)
450 perror("SIOCFRSYN");
451 else
452 printf("filter sync'd\n");
456 void zerostats()
458 ipfobj_t obj;
459 friostat_t fio;
461 obj.ipfo_rev = IPFILTER_VERSION;
462 obj.ipfo_type = IPFOBJ_IPFSTAT;
463 obj.ipfo_size = sizeof(fio);
464 obj.ipfo_ptr = &fio;
465 obj.ipfo_offset = 0;
467 if (opendevice(ipfname, 1) != -2) {
468 if (ioctl(fd, SIOCFRZST, &obj) == -1) {
469 perror("ioctl(SIOCFRZST)");
470 exit(-1);
472 showstats(&fio);
479 * read the kernel stats for packets blocked and passed
481 static void showstats(fp)
482 friostat_t *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,
488 fp->f_st[0].fr_nom);
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,
492 fp->f_st[1].fr_nom);
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()
506 struct friostat fio;
507 ipfobj_t ipfo;
508 u_32_t flags;
509 char *s;
510 int vfd;
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");
522 return 1;
525 if (ioctl(vfd, SIOCGETFS, &ipfo)) {
526 perror("ioctl(SIOCGETFS)");
527 close(vfd);
528 return 1;
530 close(vfd);
531 flags = get_flags();
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);
537 s = "";
538 if (flags & FF_LOGPASS) {
539 printf("pass");
540 s = ", ";
542 if (flags & FF_LOGBLOCK) {
543 printf("%sblock", s);
544 s = ", ";
546 if (flags & FF_LOGNOMATCH) {
547 printf("%snomatch", s);
548 s = ", ";
550 if (flags & FF_BLOCKNONIP) {
551 printf("%snonip", s);
552 s = ", ";
554 if (!*s)
555 printf("none set");
556 putchar('\n');
558 printf("Default: ");
559 if (FR_ISPASS(fio.f_defpass))
560 s = "pass";
561 else if (FR_ISBLOCK(fio.f_defpass))
562 s = "block";
563 else
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);
569 return 0;