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