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