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