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