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