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