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