xref: /titanic_52/usr/src/cmd/ipf/tools/ipftest.c (revision a1c36c8ba5112b6713dabac615bf8d56a45f0764)
1 /*
2  * Copyright (C) 1993-2001 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  *
6  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
7  * Use is subject to license terms.
8  */
9 
10 #include "ipf.h"
11 #include "ipt.h"
12 #include <sys/ioctl.h>
13 #include <sys/file.h>
14 
15 #if !defined(lint)
16 static const char sccsid[] = "@(#)ipt.c	1.19 6/3/96 (C) 1993-2000 Darren Reed";
17 static const char rcsid[] = "@(#)$Id: ipftest.c,v 1.44.2.4 2005/07/16 06:05:28 darrenr Exp $";
18 #endif
19 
20 extern	char	*optarg;
21 extern	struct frentry	*ipfilter[2][2];
22 extern	struct ipread	snoop, etherf, tcpd, pcap, iptext, iphex;
23 extern	struct ifnet	*get_unit __P((char *, int, ipf_stack_t *));
24 extern	void	init_ifp __P((void));
25 
26 int	opts = OPT_DONOTHING;
27 int	use_inet6 = 0;
28 int	pfil_delayed_copy = 0;
29 int	main __P((int, char *[]));
30 int	loadrules __P((char *, int));
31 int	kmemcpy __P((char *, long, int));
32 int     kstrncpy __P((char *, long, int n));
33 void	dumpnat __P((ipf_stack_t *ifs));
34 void	dumpstate __P((ipf_stack_t *ifs));
35 void	dumplookups __P((ipf_stack_t *ifs));
36 void	dumpgroups __P((ipf_stack_t *ifs));
37 void	drain_log __P((char *, ipf_stack_t *ifs));
38 void	fixv4sums __P((mb_t *, ip_t *));
39 ipf_stack_t *get_ifs __P((void));
40 ipf_stack_t *create_ifs __P((void));
41 
42 
43 #if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \
44 	(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \
45 	defined(__osf__) || defined(linux)
46 int ipftestioctl __P((int, ioctlcmd_t, ...));
47 int ipnattestioctl __P((int, ioctlcmd_t, ...));
48 int ipstatetestioctl __P((int, ioctlcmd_t, ...));
49 int ipauthtestioctl __P((int, ioctlcmd_t, ...));
50 int ipscantestioctl __P((int, ioctlcmd_t, ...));
51 int ipsynctestioctl __P((int, ioctlcmd_t, ...));
52 int ipooltestioctl __P((int, ioctlcmd_t, ...));
53 #else
54 int ipftestioctl __P((dev_t, ioctlcmd_t, void *));
55 int ipnattestioctl __P((dev_t, ioctlcmd_t, void *));
56 int ipstatetestioctl __P((dev_t, ioctlcmd_t, void *));
57 int ipauthtestioctl __P((dev_t, ioctlcmd_t, void *));
58 int ipsynctestioctl __P((dev_t, ioctlcmd_t, void *));
59 int ipscantestioctl __P((dev_t, ioctlcmd_t, void *));
60 int ipooltestioctl __P((dev_t, ioctlcmd_t, void *));
61 #endif
62 
63 static	ioctlfunc_t	iocfunctions[IPL_LOGSIZE] = { ipftestioctl,
64 						      ipnattestioctl,
65 						      ipstatetestioctl,
66 						      ipauthtestioctl,
67 						      ipsynctestioctl,
68 						      ipscantestioctl,
69 						      ipooltestioctl,
70 						      NULL };
71 
72 
73 int main(argc,argv)
74 int argc;
75 char *argv[];
76 {
77 	char	*datain, *iface, *ifname, *logout;
78 	int	fd, i, dir, c, loaded, dump, hlen;
79 	struct	ifnet	*ifp;
80 	struct	ipread	*r;
81 	mb_t	mb, *m;
82 	ip_t	*ip;
83 	ipf_stack_t *ifs;
84 
85 	m = &mb;
86 	dir = 0;
87 	dump = 0;
88 	hlen = 0;
89 	loaded = 0;
90 	r = &iptext;
91 	iface = NULL;
92 	logout = NULL;
93 	ifname = "anon0";
94 	datain = NULL;
95 
96 	initparse();
97 	ifs = create_ifs();
98 
99 #if defined(IPFILTER_DEFAULT_BLOCK)
100         ifs->ifs_fr_pass = FR_BLOCK|FR_NOMATCH;
101 #else
102         ifs->ifs_fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH;
103 #endif
104 	ipftuneable_alloc(ifs);
105 
106 	MUTEX_INIT(&ifs->ifs_ipf_rw, "ipf rw mutex");
107 	MUTEX_INIT(&ifs->ifs_ipf_timeoutlock, "ipf timeout lock");
108 	RWLOCK_INIT(&ifs->ifs_ipf_global, "ipf filter load/unload mutex");
109 	RWLOCK_INIT(&ifs->ifs_ipf_mutex, "ipf filter rwlock");
110 	RWLOCK_INIT(&ifs->ifs_ipf_ipidfrag, "ipf IP NAT-Frag rwlock");
111 	RWLOCK_INIT(&ifs->ifs_ipf_frcache, "ipf rule cache rwlock");
112 
113 	fr_loginit(ifs);
114 	fr_authinit(ifs);
115 	fr_fraginit(ifs);
116 	fr_stateinit(ifs);
117 	fr_natinit(ifs);
118 	appr_init(ifs);
119 	ip_lookup_init(ifs);
120 	ifs->ifs_fr_running = 1;
121 
122 	while ((c = getopt(argc, argv, "6bdDF:i:I:l:N:P:or:RT:vxX")) != -1)
123 		switch (c)
124 		{
125 		case '6' :
126 #ifdef	USE_INET6
127 			use_inet6 = 1;
128 #else
129 			fprintf(stderr, "IPv6 not supported\n");
130 			exit(1);
131 #endif
132 			break;
133 		case 'b' :
134 			opts |= OPT_BRIEF;
135 			break;
136 		case 'd' :
137 			opts |= OPT_DEBUG;
138 			break;
139 		case 'D' :
140 			dump = 1;
141 			break;
142 		case 'F' :
143 			if (strcasecmp(optarg, "pcap") == 0)
144 				r = &pcap;
145 			else if (strcasecmp(optarg, "etherfind") == 0)
146 				r = &etherf;
147 			else if (strcasecmp(optarg, "snoop") == 0)
148 				r = &snoop;
149 			else if (strcasecmp(optarg, "tcpdump") == 0)
150 				r = &tcpd;
151 			else if (strcasecmp(optarg, "hex") == 0)
152 				r = &iphex;
153 			else if (strcasecmp(optarg, "text") == 0)
154 				r = &iptext;
155 			break;
156 		case 'i' :
157 			datain = optarg;
158 			break;
159 		case 'I' :
160 			ifname = optarg;
161 			break;
162 		case 'l' :
163 			logout = optarg;
164 			break;
165 		case 'o' :
166 			opts |= OPT_SAVEOUT;
167 			break;
168 		case 'r' :
169 			if (ipf_parsefile(-1, ipf_addrule, iocfunctions,
170 					  optarg) == -1)
171 				return -1;
172 			loaded = 1;
173 			break;
174 		case 'R' :
175 			opts |= OPT_NORESOLVE;
176 			break;
177 		case 'v' :
178 			opts |= OPT_VERBOSE;
179 			break;
180 		case 'N' :
181 			if (ipnat_parsefile(-1, ipnat_addrule, ipnattestioctl,
182 					    optarg) == -1)
183 				return -1;
184 			loaded = 1;
185 			opts |= OPT_NAT;
186 			break;
187 		case 'P' :
188 			if (ippool_parsefile(-1, optarg, ipooltestioctl) == -1)
189 				return -1;
190 			loaded = 1;
191 			break;
192 		case 'T' :
193 			ipf_dotuning(-1, optarg, ipftestioctl);
194 			break;
195 		case 'x' :
196 			opts |= OPT_HEX;
197 			break;
198 		}
199 
200 	if (loaded == 0) {
201 		(void)fprintf(stderr,"no rules loaded\n");
202 		exit(-1);
203 	}
204 
205 	if (opts & OPT_SAVEOUT)
206 		init_ifp();
207 
208 	if (datain)
209 		fd = (*r->r_open)(datain);
210 	else
211 		fd = (*r->r_open)("-");
212 
213 	if (fd < 0)
214 		exit(-1);
215 
216 	ip = MTOD(m, ip_t *);
217 	while ((i = (*r->r_readip)(MTOD(m, char *), sizeof(m->mb_buf),
218 				    &iface, &dir)) > 0) {
219 		if (iface == NULL || *iface == '\0')
220 			iface = ifname;
221 		ifp = get_unit(iface, IP_V(ip), ifs);
222 		if (ifp == NULL) {
223 			fprintf(stderr, "out of memory\n");
224 			exit(1);
225 		}
226 		if (!use_inet6) {
227 			ip->ip_off = ntohs(ip->ip_off);
228 			ip->ip_len = ntohs(ip->ip_len);
229 			if (r->r_flags & R_DO_CKSUM)
230 				fixv4sums(m, ip);
231 			hlen = IP_HL(ip) << 2;
232 		}
233 #ifdef	USE_INET6
234 		else
235 			hlen = sizeof(ip6_t);
236 #endif
237 		/* ipfr_slowtimer(); */
238 		m = &mb;
239 		m->mb_len = i;
240 		i = fr_check(ip, hlen, ifp, dir, &m, ifs);
241 		if ((opts & OPT_NAT) == 0)
242 			switch (i)
243 			{
244 			case -4 :
245 				(void)printf("preauth");
246 				break;
247 			case -3 :
248 				(void)printf("account");
249 				break;
250 			case -2 :
251 				(void)printf("auth");
252 				break;
253 			case -1 :
254 				(void)printf("block");
255 				break;
256 			case 0 :
257 				(void)printf("pass");
258 				break;
259 			case 1 :
260 				(void)printf("nomatch");
261 				break;
262 			case 3 :
263 				(void)printf("block return-rst");
264 				break;
265 			case 4 :
266 				(void)printf("block return-icmp");
267 				break;
268 			case 5 :
269 				(void)printf("block return-icmp-as-dest");
270 				break;
271 			default :
272 				(void)printf("recognised return %#x\n", i);
273 				break;
274 			}
275 		if (!use_inet6) {
276 			ip->ip_off = htons(ip->ip_off);
277 			ip->ip_len = htons(ip->ip_len);
278 		}
279 
280 		if (!(opts & OPT_BRIEF)) {
281 			putchar(' ');
282 			printpacket(ip);
283 			printf("--------------");
284 		} else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF))
285 			printpacket(ip);
286 		if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL))
287 #if  defined(__sgi) && (IRIX < 60500)
288 			(*ifp->if_output)(ifp, (void *)m, NULL);
289 #else
290 # if TRU64 >= 1885
291 			(*ifp->if_output)(ifp, (void *)m, NULL, 0, 0);
292 # else
293 			(*ifp->if_output)(ifp, (void *)m, NULL, 0);
294 # endif
295 #endif
296 		if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF))
297 			putchar('\n');
298 		dir = 0;
299 		if (iface != ifname) {
300 			free(iface);
301 			iface = ifname;
302 		}
303 		m = &mb;
304 	}
305 	(*r->r_close)();
306 
307 	if (logout != NULL) {
308 		drain_log(logout, ifs);
309 	}
310 
311 	if (dump == 1)  {
312 		dumpnat(ifs);
313 		dumpstate(ifs);
314 		dumplookups(ifs);
315 		dumpgroups(ifs);
316 	}
317 
318 	fr_deinitialise(ifs);
319 
320 	return 0;
321 }
322 
323 
324 #if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \
325 	(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \
326 	defined(__osf__) || defined(linux)
327 int ipftestioctl(int dev, ioctlcmd_t cmd, ...)
328 {
329 	caddr_t data;
330 	va_list ap;
331 	int i;
332 
333 	va_start(ap, cmd);
334 	data = va_arg(ap, caddr_t);
335 	va_end(ap);
336 
337 	i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD);
338 	if (opts & OPT_DEBUG)
339 		fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n",
340 			(u_int)cmd, data, i);
341 	if (i != 0) {
342 		errno = i;
343 		return -1;
344 	}
345 	return 0;
346 }
347 
348 
349 int ipnattestioctl(int dev, ioctlcmd_t cmd, ...)
350 {
351 	caddr_t data;
352 	va_list ap;
353 	int i;
354 
355 	va_start(ap, cmd);
356 	data = va_arg(ap, caddr_t);
357 	va_end(ap);
358 
359 	i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD);
360 	if (opts & OPT_DEBUG)
361 		fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n",
362 			(u_int)cmd, data, i);
363 	if (i != 0) {
364 		errno = i;
365 		return -1;
366 	}
367 	return 0;
368 }
369 
370 
371 int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...)
372 {
373 	caddr_t data;
374 	va_list ap;
375 	int i;
376 
377 	va_start(ap, cmd);
378 	data = va_arg(ap, caddr_t);
379 	va_end(ap);
380 
381 	i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
382 	if ((opts & OPT_DEBUG) || (i != 0))
383 		fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n",
384 			(u_int)cmd, data, i);
385 	if (i != 0) {
386 		errno = i;
387 		return -1;
388 	}
389 	return 0;
390 }
391 
392 
393 int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...)
394 {
395 	caddr_t data;
396 	va_list ap;
397 	int i;
398 
399 	va_start(ap, cmd);
400 	data = va_arg(ap, caddr_t);
401 	va_end(ap);
402 
403 	i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
404 	if ((opts & OPT_DEBUG) || (i != 0))
405 		fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n",
406 			(u_int)cmd, data, i);
407 	if (i != 0) {
408 		errno = i;
409 		return -1;
410 	}
411 	return 0;
412 }
413 
414 
415 int ipscantestioctl(int dev, ioctlcmd_t cmd, ...)
416 {
417 	caddr_t data;
418 	va_list ap;
419 	int i;
420 
421 	va_start(ap, cmd);
422 	data = va_arg(ap, caddr_t);
423 	va_end(ap);
424 
425 	i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
426 	if ((opts & OPT_DEBUG) || (i != 0))
427 		fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n",
428 			(u_int)cmd, data, i);
429 	if (i != 0) {
430 		errno = i;
431 		return -1;
432 	}
433 	return 0;
434 }
435 
436 
437 int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...)
438 {
439 	caddr_t data;
440 	va_list ap;
441 	int i;
442 
443 	va_start(ap, cmd);
444 	data = va_arg(ap, caddr_t);
445 	va_end(ap);
446 
447 	i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
448 	if ((opts & OPT_DEBUG) || (i != 0))
449 		fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n",
450 			(u_int)cmd, data, i);
451 	if (i != 0) {
452 		errno = i;
453 		return -1;
454 	}
455 	return 0;
456 }
457 
458 
459 int ipooltestioctl(int dev, ioctlcmd_t cmd, ...)
460 {
461 	caddr_t data;
462 	va_list ap;
463 	int i;
464 
465 	va_start(ap, cmd);
466 	data = va_arg(ap, caddr_t);
467 	va_end(ap);
468 
469 	i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
470 	if ((opts & OPT_DEBUG) || (i != 0))
471 		fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n",
472 			(u_int)cmd, data, i);
473 	if (i != 0) {
474 		errno = i;
475 		return -1;
476 	}
477 	return 0;
478 }
479 #else
480 int ipftestioctl(dev, cmd, data)
481 dev_t dev;
482 ioctlcmd_t cmd;
483 void *data;
484 {
485 	int i;
486 
487 	i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD);
488 	if ((opts & OPT_DEBUG) || (i != 0))
489 		fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", cmd, data, i);
490 	if (i != 0) {
491 		errno = i;
492 		return -1;
493 	}
494 	return 0;
495 }
496 
497 
498 int ipnattestioctl(dev, cmd, data)
499 dev_t dev;
500 ioctlcmd_t cmd;
501 void *data;
502 {
503 	int i;
504 
505 	i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD);
506 	if ((opts & OPT_DEBUG) || (i != 0))
507 		fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", cmd, data, i);
508 	if (i != 0) {
509 		errno = i;
510 		return -1;
511 	}
512 	return 0;
513 }
514 
515 
516 int ipstatetestioctl(dev, cmd, data)
517 dev_t dev;
518 ioctlcmd_t cmd;
519 void *data;
520 {
521 	int i;
522 
523 	i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
524 	if ((opts & OPT_DEBUG) || (i != 0))
525 		fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", cmd, data, i);
526 	if (i != 0) {
527 		errno = i;
528 		return -1;
529 	}
530 	return 0;
531 }
532 
533 
534 int ipauthtestioctl(dev, cmd, data)
535 dev_t dev;
536 ioctlcmd_t cmd;
537 void *data;
538 {
539 	int i;
540 
541 	i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
542 	if ((opts & OPT_DEBUG) || (i != 0))
543 		fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", cmd, data, i);
544 	if (i != 0) {
545 		errno = i;
546 		return -1;
547 	}
548 	return 0;
549 }
550 
551 
552 int ipsynctestioctl(dev, cmd, data)
553 dev_t dev;
554 ioctlcmd_t cmd;
555 void *data;
556 {
557 	int i;
558 
559 	i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
560 	if ((opts & OPT_DEBUG) || (i != 0))
561 		fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", cmd, data, i);
562 	if (i != 0) {
563 		errno = i;
564 		return -1;
565 	}
566 	return 0;
567 }
568 
569 
570 int ipscantestioctl(dev, cmd, data)
571 dev_t dev;
572 ioctlcmd_t cmd;
573 void *data;
574 {
575 	int i;
576 
577 	i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
578 	if ((opts & OPT_DEBUG) || (i != 0))
579 		fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", cmd, data, i);
580 	if (i != 0) {
581 		errno = i;
582 		return -1;
583 	}
584 	return 0;
585 }
586 
587 
588 int ipooltestioctl(dev, cmd, data)
589 dev_t dev;
590 ioctlcmd_t cmd;
591 void *data;
592 {
593 	int i;
594 
595 	i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
596 	if (opts & OPT_DEBUG)
597 		fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", cmd, data, i);
598 	if (i != 0) {
599 		errno = i;
600 		return -1;
601 	}
602 	return 0;
603 }
604 #endif
605 
606 
607 int kmemcpy(addr, offset, size)
608 char *addr;
609 long offset;
610 int size;
611 {
612 	bcopy((char *)offset, addr, size);
613 	return 0;
614 }
615 
616 
617 int kstrncpy(buf, pos, n)
618 char *buf;
619 long pos;
620 int n;
621 {
622 	char *ptr;
623 
624 	ptr = (char *)pos;
625 
626 	while ((n-- > 0) && (*buf++ = *ptr++))
627 		;
628 	return 0;
629 }
630 
631 
632 /*
633  * Display the built up NAT table rules and mapping entries.
634  */
635 void dumpnat(ifs)
636 	ipf_stack_t *ifs;
637 {
638 	ipnat_t	*ipn;
639 	nat_t	*nat;
640 
641 	printf("List of active MAP/Redirect filters:\n");
642 	for (ipn = ifs->ifs_nat_list; ipn != NULL; ipn = ipn->in_next)
643 		printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
644 	printf("\nList of active sessions:\n");
645 	for (nat = ifs->ifs_nat_instances; nat; nat = nat->nat_next) {
646 		printactivenat(nat, opts, 0);
647 		if (nat->nat_aps)
648 			printaps(nat->nat_aps, opts);
649 	}
650 }
651 
652 
653 /*
654  * Display the built up state table rules and mapping entries.
655  */
656 void dumpstate(ifs)
657 	ipf_stack_t *ifs;
658 {
659 	ipstate_t *ips;
660 
661 	printf("List of active state sessions:\n");
662 	for (ips = ifs->ifs_ips_list; ips != NULL; )
663 		ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE),
664 				 ifs->ifs_fr_ticks);
665 }
666 
667 
668 void dumplookups(ifs)
669 	ipf_stack_t *ifs;
670 {
671 	iphtable_t *iph;
672 	ip_pool_t *ipl;
673 	int i;
674 
675 	printf("List of configured pools\n");
676 	for (i = 0; i < IPL_LOGSIZE; i++)
677 		for (ipl = ifs->ifs_ip_pool_list[i]; ipl != NULL;
678 		    ipl = ipl->ipo_next)
679 			printpool(ipl, bcopywrap, NULL, opts);
680 
681 	printf("List of configured hash tables\n");
682 	for (i = 0; i < IPL_LOGSIZE; i++)
683 		for (iph = ifs->ifs_ipf_htables[i]; iph != NULL;
684 		     iph = iph->iph_next)
685 			printhash(iph, bcopywrap, NULL, opts);
686 }
687 
688 
689 void dumpgroups(ifs)
690 	ipf_stack_t *ifs;
691 {
692 	frgroup_t *fg;
693 	frentry_t *fr;
694 	int i;
695 
696 	printf("List of groups configured (set 0)\n");
697 	for (i = 0; i < IPL_LOGSIZE; i++)
698 		for (fg =  ifs->ifs_ipfgroups[i][0]; fg != NULL;
699 		    fg = fg->fg_next) {
700 			printf("Dev.%d. Group %s Ref %d Flags %#x\n",
701 				i, fg->fg_name, fg->fg_ref, fg->fg_flags);
702 			for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) {
703 #ifdef	USE_QUAD_T
704 				printf("%qu ",(unsigned long long)fr->fr_hits);
705 #else
706 				printf("%ld ", fr->fr_hits);
707 #endif
708 				printfr(fr, ipftestioctl);
709 			}
710 		}
711 
712 	printf("List of groups configured (set 1)\n");
713 	for (i = 0; i < IPL_LOGSIZE; i++)
714 		for (fg =  ifs->ifs_ipfgroups[i][1]; fg != NULL;
715 		    fg = fg->fg_next) {
716 			printf("Dev.%d. Group %s Ref %d Flags %#x\n",
717 				i, fg->fg_name, fg->fg_ref, fg->fg_flags);
718 			for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) {
719 #ifdef	USE_QUAD_T
720 				printf("%qu ",(unsigned long long)fr->fr_hits);
721 #else
722 				printf("%ld ", fr->fr_hits);
723 #endif
724 				printfr(fr, ipftestioctl);
725 			}
726 		}
727 }
728 
729 
730 void drain_log(filename, ifs)
731 char *filename;
732 ipf_stack_t *ifs;
733 {
734 	char buffer[DEFAULT_IPFLOGSIZE];
735 	struct iovec iov;
736 	struct uio uio;
737 	size_t resid;
738 	int fd, i;
739 
740 	fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
741 	if (fd == -1) {
742 		perror("drain_log:open");
743 		return;
744 	}
745 
746 	for (i = 0; i <= IPL_LOGMAX; i++)
747 		while (1) {
748 			bzero((char *)&iov, sizeof(iov));
749 			iov.iov_base = buffer;
750 			iov.iov_len = sizeof(buffer);
751 
752 			bzero((char *)&uio, sizeof(uio));
753 			uio.uio_iov = &iov;
754 			uio.uio_iovcnt = 1;
755 			uio.uio_resid = iov.iov_len;
756 			resid = uio.uio_resid;
757 
758 			if (ipflog_read(i, &uio, ifs) == 0) {
759 				/*
760 				 * If nothing was read then break out.
761 				 */
762 				if (uio.uio_resid == resid)
763 					break;
764 				write(fd, buffer, resid - uio.uio_resid);
765 			} else
766 				break;
767 	}
768 
769 	close(fd);
770 }
771 
772 
773 void fixv4sums(m, ip)
774 mb_t *m;
775 ip_t *ip;
776 {
777 	u_char *csump, *hdr;
778 
779 	ip->ip_sum = 0;
780 	ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2);
781 
782 	csump = (u_char *)ip;
783 	csump += IP_HL(ip) << 2;
784 
785 	switch (ip->ip_p)
786 	{
787 	case IPPROTO_TCP :
788 		hdr = csump;
789 		csump += offsetof(tcphdr_t, th_sum);
790 		break;
791 	case IPPROTO_UDP :
792 		hdr = csump;
793 		csump += offsetof(udphdr_t, uh_sum);
794 		break;
795 	default :
796 		csump = NULL;
797 		hdr = NULL;
798 		break;
799 	}
800 	if (hdr != NULL) {
801 		*csump = 0;
802 		*(u_short *)csump = fr_cksum(m, ip, ip->ip_p, hdr);
803 	}
804 }
805 
806 ipf_stack_t *gifs;
807 
808 /*
809  * Allocate and keep pointer for get_ifs()
810  */
811 ipf_stack_t *
812 create_ifs()
813 {
814 	ipf_stack_t *ifs;
815 
816 	KMALLOCS(ifs, ipf_stack_t *, sizeof (*ifs));
817 	bzero(ifs, sizeof (*ifs));
818 	gifs = ifs;
819 	return (ifs);
820 }
821 
822 ipf_stack_t *
823 get_ifs()
824 {
825 	return (gifs);
826 }
827