xref: /illumos-gate/usr/src/cmd/ipf/tools/ip_fil.c (revision ae7a42b1)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright (C) 1993-2001, 2003 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate  *
633f2fefdSDarren Reed  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
77c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
87c478bd9Sstevel@tonic-gate  */
97c478bd9Sstevel@tonic-gate 
10*ae7a42b1SToomas Soome #ifdef SOLARIS
11*ae7a42b1SToomas Soome #undef	SOLARIS
12*ae7a42b1SToomas Soome #endif
13*ae7a42b1SToomas Soome #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
14*ae7a42b1SToomas Soome #define	SOLARIS	(1)
15*ae7a42b1SToomas Soome #else
16*ae7a42b1SToomas Soome #define	SOLARIS	(0)
177c478bd9Sstevel@tonic-gate #endif
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate #include <sys/param.h>
207c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__) && !defined(__FreeBSD_version)
217c478bd9Sstevel@tonic-gate # if defined(IPFILTER_LKM)
227c478bd9Sstevel@tonic-gate #  ifndef __FreeBSD_cc_version
237c478bd9Sstevel@tonic-gate #   include <osreldate.h>
247c478bd9Sstevel@tonic-gate #  else
257c478bd9Sstevel@tonic-gate #   if __FreeBSD_cc_version < 430000
267c478bd9Sstevel@tonic-gate #    include <osreldate.h>
277c478bd9Sstevel@tonic-gate #   endif
287c478bd9Sstevel@tonic-gate #  endif
297c478bd9Sstevel@tonic-gate # endif
307c478bd9Sstevel@tonic-gate #endif
317c478bd9Sstevel@tonic-gate #include <sys/errno.h>
32ab25eeb5Syz #if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL)
33ab25eeb5Syz # include <sys/kern_svcs.h>
34ab25eeb5Syz #endif
357c478bd9Sstevel@tonic-gate #include <sys/types.h>
36ab25eeb5Syz #define _KERNEL
37ab25eeb5Syz #define KERNEL
38ab25eeb5Syz #ifdef __OpenBSD__
397c478bd9Sstevel@tonic-gate struct file;
407c478bd9Sstevel@tonic-gate #endif
41ab25eeb5Syz #include <sys/uio.h>
42ab25eeb5Syz #undef _KERNEL
43ab25eeb5Syz #undef KERNEL
447c478bd9Sstevel@tonic-gate #include <sys/file.h>
457c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
467c478bd9Sstevel@tonic-gate #ifdef __sgi
477c478bd9Sstevel@tonic-gate # include <sys/ptimers.h>
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate #include <sys/time.h>
50af5f29ddSToomas Soome #if !defined(SOLARIS)
517c478bd9Sstevel@tonic-gate # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
527c478bd9Sstevel@tonic-gate #  include <sys/dirent.h>
537c478bd9Sstevel@tonic-gate # else
547c478bd9Sstevel@tonic-gate #  include <sys/dir.h>
557c478bd9Sstevel@tonic-gate # endif
567c478bd9Sstevel@tonic-gate #else
577c478bd9Sstevel@tonic-gate # include <sys/filio.h>
587c478bd9Sstevel@tonic-gate #endif
59ab25eeb5Syz #ifndef linux
60ab25eeb5Syz # include <sys/protosw.h>
61ab25eeb5Syz #endif
627c478bd9Sstevel@tonic-gate #include <sys/socket.h>
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #include <stdio.h>
657c478bd9Sstevel@tonic-gate #include <string.h>
667c478bd9Sstevel@tonic-gate #include <stdlib.h>
677c478bd9Sstevel@tonic-gate #include <ctype.h>
687c478bd9Sstevel@tonic-gate #include <fcntl.h>
69f4b3ec61Sdh #include <sys/zone.h>
70ab25eeb5Syz #include <arpa/inet.h>
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate #ifdef __hpux
737c478bd9Sstevel@tonic-gate # define _NET_ROUTE_INCLUDED
747c478bd9Sstevel@tonic-gate #endif
757c478bd9Sstevel@tonic-gate #include <net/if.h>
767c478bd9Sstevel@tonic-gate #ifdef sun
777c478bd9Sstevel@tonic-gate # include <net/af.h>
787c478bd9Sstevel@tonic-gate #endif
797c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000
807c478bd9Sstevel@tonic-gate # include <net/if_var.h>
817c478bd9Sstevel@tonic-gate #endif
827c478bd9Sstevel@tonic-gate #ifdef __sgi
837c478bd9Sstevel@tonic-gate #include <sys/debug.h>
847c478bd9Sstevel@tonic-gate # ifdef IFF_DRVRLOCK /* IRIX6 */
857c478bd9Sstevel@tonic-gate #include <sys/hashing.h>
867c478bd9Sstevel@tonic-gate # endif
877c478bd9Sstevel@tonic-gate #endif
88ab25eeb5Syz #if defined(__FreeBSD__)
89ab25eeb5Syz # include "radix_ipf.h"
90ab25eeb5Syz #endif
917c478bd9Sstevel@tonic-gate #include <net/route.h>
927c478bd9Sstevel@tonic-gate #include <netinet/in.h>
937c478bd9Sstevel@tonic-gate #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \
94ab25eeb5Syz     !defined(__hpux) && !defined(linux)
957c478bd9Sstevel@tonic-gate # include <netinet/in_var.h>
967c478bd9Sstevel@tonic-gate #endif
977c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h>
987c478bd9Sstevel@tonic-gate #include <netinet/ip.h>
99ab25eeb5Syz #if !defined(linux)
100ab25eeb5Syz # include <netinet/ip_var.h>
101ab25eeb5Syz #endif
1027c478bd9Sstevel@tonic-gate #include <netinet/tcp.h>
1037c478bd9Sstevel@tonic-gate #if defined(__osf__)
1047c478bd9Sstevel@tonic-gate # include <netinet/tcp_timer.h>
1057c478bd9Sstevel@tonic-gate #endif
106ab25eeb5Syz #if defined(__osf__) || defined(__hpux) || defined(__sgi)
107ab25eeb5Syz # include "radix_ipf_local.h"
108ab25eeb5Syz # define _RADIX_H_
109ab25eeb5Syz #endif
1107c478bd9Sstevel@tonic-gate #include <netinet/udp.h>
1117c478bd9Sstevel@tonic-gate #include <netinet/tcpip.h>
1127c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h>
1137c478bd9Sstevel@tonic-gate #include <unistd.h>
1147c478bd9Sstevel@tonic-gate #include <syslog.h>
1157c478bd9Sstevel@tonic-gate #ifdef __hpux
1167c478bd9Sstevel@tonic-gate # undef _NET_ROUTE_INCLUDED
1177c478bd9Sstevel@tonic-gate #endif
1187c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h"
1197c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h"
1207c478bd9Sstevel@tonic-gate #include "netinet/ip_nat.h"
1217c478bd9Sstevel@tonic-gate #include "netinet/ip_frag.h"
1227c478bd9Sstevel@tonic-gate #include "netinet/ip_state.h"
1237c478bd9Sstevel@tonic-gate #include "netinet/ip_proxy.h"
1247c478bd9Sstevel@tonic-gate #include "netinet/ip_auth.h"
1257c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SYNC
1267c478bd9Sstevel@tonic-gate #include "netinet/ip_sync.h"
1277c478bd9Sstevel@tonic-gate #endif
1287c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SCAN
1297c478bd9Sstevel@tonic-gate #include "netinet/ip_scan.h"
1307c478bd9Sstevel@tonic-gate #endif
1317c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h"
1327c478bd9Sstevel@tonic-gate #ifdef IPFILTER_COMPILED
1337c478bd9Sstevel@tonic-gate # include "netinet/ip_rules.h"
1347c478bd9Sstevel@tonic-gate #endif
135f4b3ec61Sdh #include "netinet/ipf_stack.h"
1367c478bd9Sstevel@tonic-gate #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
1377c478bd9Sstevel@tonic-gate # include <sys/malloc.h>
1387c478bd9Sstevel@tonic-gate #endif
1397c478bd9Sstevel@tonic-gate #ifdef __hpux
1407c478bd9Sstevel@tonic-gate struct rtentry;
1417c478bd9Sstevel@tonic-gate #endif
142ab25eeb5Syz #include "md5.h"
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate #if !defined(__osf__)
1467c478bd9Sstevel@tonic-gate extern	struct	protosw	inetsw[];
1477c478bd9Sstevel@tonic-gate #endif
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate #include "ipt.h"
1507c478bd9Sstevel@tonic-gate static	struct	ifnet **ifneta = NULL;
1517c478bd9Sstevel@tonic-gate static	int	nifs = 0;
1527c478bd9Sstevel@tonic-gate 
153f4b3ec61Sdh static	int	frzerostats __P((caddr_t, ipf_stack_t *ifs));
154ab25eeb5Syz static	void	fr_setifpaddr __P((struct ifnet *, char *));
1557c478bd9Sstevel@tonic-gate void	init_ifp __P((void));
156ab25eeb5Syz #if defined(__sgi) && (IRIX < 60500)
1577c478bd9Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1587c478bd9Sstevel@tonic-gate 			       struct sockaddr *));
1597c478bd9Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1607c478bd9Sstevel@tonic-gate 				  struct sockaddr *));
1617c478bd9Sstevel@tonic-gate #else
1627c478bd9Sstevel@tonic-gate # if TRU64 >= 1885
1637c478bd9Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1647c478bd9Sstevel@tonic-gate 			       struct sockaddr *, struct rtentry *, char *));
1657c478bd9Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1667c478bd9Sstevel@tonic-gate 				  struct sockaddr *, struct rtentry *, char *));
1677c478bd9Sstevel@tonic-gate # else
1687c478bd9Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1697c478bd9Sstevel@tonic-gate 			       struct sockaddr *, struct rtentry *));
1707c478bd9Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1717c478bd9Sstevel@tonic-gate 				  struct sockaddr *, struct rtentry *));
1727c478bd9Sstevel@tonic-gate # endif
1737c478bd9Sstevel@tonic-gate #endif
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 
iplattach(ifs)1767ddc9b1aSDarren Reed int iplattach(ifs)
177f4b3ec61Sdh ipf_stack_t *ifs;
1787c478bd9Sstevel@tonic-gate {
179f4b3ec61Sdh 	ifs->ifs_fr_running = 1;
1807c478bd9Sstevel@tonic-gate 	return 0;
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 
ipldetach(ifs)184f4b3ec61Sdh int ipldetach(ifs)
185f4b3ec61Sdh ipf_stack_t *ifs;
1867c478bd9Sstevel@tonic-gate {
187f4b3ec61Sdh 	ifs->ifs_fr_running = -1;
1887c478bd9Sstevel@tonic-gate 	return 0;
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 
frzerostats(data,ifs)192f4b3ec61Sdh static	int	frzerostats(data, ifs)
1937c478bd9Sstevel@tonic-gate caddr_t	data;
194f4b3ec61Sdh ipf_stack_t *ifs;
1957c478bd9Sstevel@tonic-gate {
1967c478bd9Sstevel@tonic-gate 	friostat_t fio;
1977c478bd9Sstevel@tonic-gate 	int error;
1987c478bd9Sstevel@tonic-gate 
199f4b3ec61Sdh 	fr_getstat(&fio, ifs);
2007c478bd9Sstevel@tonic-gate 	error = copyoutptr(&fio, data, sizeof(fio));
2017c478bd9Sstevel@tonic-gate 	if (error)
2027c478bd9Sstevel@tonic-gate 		return EFAULT;
2037c478bd9Sstevel@tonic-gate 
204f4b3ec61Sdh 	bzero((char *)ifs->ifs_frstats, sizeof(*ifs->ifs_frstats) * 2);
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	return 0;
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate /*
2117c478bd9Sstevel@tonic-gate  * Filter ioctl interface.
2127c478bd9Sstevel@tonic-gate  */
iplioctl(dev,cmd,data,mode)2137c478bd9Sstevel@tonic-gate int iplioctl(dev, cmd, data, mode)
2147c478bd9Sstevel@tonic-gate int dev;
215ab25eeb5Syz ioctlcmd_t cmd;
2167c478bd9Sstevel@tonic-gate caddr_t data;
2177c478bd9Sstevel@tonic-gate int mode;
2187c478bd9Sstevel@tonic-gate {
219f4b3ec61Sdh 	int error = 0, unit = 0, tmp, uid;
2207c478bd9Sstevel@tonic-gate 	friostat_t fio;
221f4b3ec61Sdh 	ipf_stack_t *ifs;
222f4b3ec61Sdh 	extern ipf_stack_t *get_ifs();
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	unit = dev;
225f4b3ec61Sdh 	uid = getuid();
226f4b3ec61Sdh 
227f4b3ec61Sdh 	ifs = get_ifs();
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	SPL_NET(s);
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGNAT) {
232f4b3ec61Sdh 		if (ifs->ifs_fr_running > 0)
233f4b3ec61Sdh 			error = fr_nat_ioctl(data, cmd, mode, uid, NULL, ifs);
2347c478bd9Sstevel@tonic-gate 		else
2357c478bd9Sstevel@tonic-gate 			error = EIO;
2367c478bd9Sstevel@tonic-gate 		SPL_X(s);
2377c478bd9Sstevel@tonic-gate 		return error;
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGSTATE) {
240f4b3ec61Sdh 		if (ifs->ifs_fr_running > 0)
241f4b3ec61Sdh 			error = fr_state_ioctl(data, cmd, mode, uid, NULL, ifs);
2427c478bd9Sstevel@tonic-gate 		else
2437c478bd9Sstevel@tonic-gate 			error = EIO;
2447c478bd9Sstevel@tonic-gate 		SPL_X(s);
2457c478bd9Sstevel@tonic-gate 		return error;
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGAUTH) {
248f4b3ec61Sdh 		if (ifs->ifs_fr_running > 0) {
249ab25eeb5Syz 			if ((cmd == (ioctlcmd_t)SIOCADAFR) ||
250ab25eeb5Syz 			    (cmd == (ioctlcmd_t)SIOCRMAFR)) {
2517c478bd9Sstevel@tonic-gate 				if (!(mode & FWRITE)) {
2527c478bd9Sstevel@tonic-gate 					error = EPERM;
2537c478bd9Sstevel@tonic-gate 				} else {
2547c478bd9Sstevel@tonic-gate 					error = frrequest(unit, cmd, data,
255f4b3ec61Sdh 					    ifs->ifs_fr_active, 1, ifs);
2567c478bd9Sstevel@tonic-gate 				}
2577c478bd9Sstevel@tonic-gate 			} else {
25833f2fefdSDarren Reed 				error = fr_auth_ioctl(data, cmd, mode, uid,
25933f2fefdSDarren Reed 						      NULL, ifs);
2607c478bd9Sstevel@tonic-gate 			}
2617c478bd9Sstevel@tonic-gate 		} else
2627c478bd9Sstevel@tonic-gate 			error = EIO;
2637c478bd9Sstevel@tonic-gate 		SPL_X(s);
2647c478bd9Sstevel@tonic-gate 		return error;
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGSYNC) {
2677c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SYNC
268f4b3ec61Sdh 		if (ifs->ifs_fr_running > 0)
2697c478bd9Sstevel@tonic-gate 			error = fr_sync_ioctl(data, cmd, mode);
2707c478bd9Sstevel@tonic-gate 		else
2717c478bd9Sstevel@tonic-gate #endif
2727c478bd9Sstevel@tonic-gate 			error = EIO;
2737c478bd9Sstevel@tonic-gate 		SPL_X(s);
2747c478bd9Sstevel@tonic-gate 		return error;
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGSCAN) {
2777c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SCAN
278f4b3ec61Sdh 		if (ifs->ifs_fr_running > 0)
2797c478bd9Sstevel@tonic-gate 			error = fr_scan_ioctl(data, cmd, mode);
2807c478bd9Sstevel@tonic-gate 		else
2817c478bd9Sstevel@tonic-gate #endif
2827c478bd9Sstevel@tonic-gate 			error = EIO;
2837c478bd9Sstevel@tonic-gate 		SPL_X(s);
2847c478bd9Sstevel@tonic-gate 		return error;
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGLOOKUP) {
287f4b3ec61Sdh 		if (ifs->ifs_fr_running > 0)
288f4b3ec61Sdh 			error = ip_lookup_ioctl(data, cmd, mode, uid,
289f4b3ec61Sdh 			    NULL, ifs);
2907c478bd9Sstevel@tonic-gate 		else
2917c478bd9Sstevel@tonic-gate 			error = EIO;
2927c478bd9Sstevel@tonic-gate 		SPL_X(s);
2937c478bd9Sstevel@tonic-gate 		return error;
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	switch (cmd)
2977c478bd9Sstevel@tonic-gate 	{
2987c478bd9Sstevel@tonic-gate 	case FIONREAD :
2997c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOG
300f4b3ec61Sdh 		error = COPYOUT(&ifs->ifs_iplused[IPL_LOGIPF], (caddr_t)data,
301f4b3ec61Sdh 			       sizeof(ifs->ifs_iplused[IPL_LOGIPF]));
3027c478bd9Sstevel@tonic-gate #endif
3037c478bd9Sstevel@tonic-gate 		break;
3047c478bd9Sstevel@tonic-gate 	case SIOCFRENB :
3057c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3067c478bd9Sstevel@tonic-gate 			error = EPERM;
3077c478bd9Sstevel@tonic-gate 		else {
3087c478bd9Sstevel@tonic-gate 			error = COPYIN(data, &tmp, sizeof(tmp));
3097c478bd9Sstevel@tonic-gate 			if (error)
3107c478bd9Sstevel@tonic-gate 				break;
3117c478bd9Sstevel@tonic-gate 			if (tmp)
3127ddc9b1aSDarren Reed 				error = iplattach(ifs);
3137c478bd9Sstevel@tonic-gate 			else
314f4b3ec61Sdh 				error = ipldetach(ifs);
3157c478bd9Sstevel@tonic-gate 		}
3167c478bd9Sstevel@tonic-gate 		break;
317ab25eeb5Syz 	case SIOCIPFSET :
318ab25eeb5Syz 		if (!(mode & FWRITE)) {
319ab25eeb5Syz 			error = EPERM;
320ab25eeb5Syz 			break;
321ab25eeb5Syz 		}
322af5f29ddSToomas Soome 		/* FALLTHROUGH */
323ab25eeb5Syz 	case SIOCIPFGETNEXT :
324ab25eeb5Syz 	case SIOCIPFGET :
325f4b3ec61Sdh 		error = fr_ipftune(cmd, (void *)data, ifs);
326ab25eeb5Syz 		break;
3277c478bd9Sstevel@tonic-gate 	case SIOCSETFF :
3287c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3297c478bd9Sstevel@tonic-gate 			error = EPERM;
3307c478bd9Sstevel@tonic-gate 		else
331f4b3ec61Sdh 			error = COPYIN(data, &ifs->ifs_fr_flags,
332f4b3ec61Sdh 			    sizeof(ifs->ifs_fr_flags));
3337c478bd9Sstevel@tonic-gate 		break;
3347c478bd9Sstevel@tonic-gate 	case SIOCGETFF :
335f4b3ec61Sdh 		error = COPYOUT(&ifs->ifs_fr_flags, data,
336f4b3ec61Sdh 		    sizeof(ifs->ifs_fr_flags));
3377c478bd9Sstevel@tonic-gate 		break;
3387c478bd9Sstevel@tonic-gate 	case SIOCFUNCL :
3397c478bd9Sstevel@tonic-gate 		error = fr_resolvefunc(data);
3407c478bd9Sstevel@tonic-gate 		break;
3417c478bd9Sstevel@tonic-gate 	case SIOCINAFR :
3427c478bd9Sstevel@tonic-gate 	case SIOCRMAFR :
3437c478bd9Sstevel@tonic-gate 	case SIOCADAFR :
3447c478bd9Sstevel@tonic-gate 	case SIOCZRLST :
3457c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3467c478bd9Sstevel@tonic-gate 			error = EPERM;
3477c478bd9Sstevel@tonic-gate 		else
348f4b3ec61Sdh 			error = frrequest(unit, cmd, data,
349f4b3ec61Sdh 			    ifs->ifs_fr_active, 1, ifs);
3507c478bd9Sstevel@tonic-gate 		break;
3517c478bd9Sstevel@tonic-gate 	case SIOCINIFR :
3527c478bd9Sstevel@tonic-gate 	case SIOCRMIFR :
3537c478bd9Sstevel@tonic-gate 	case SIOCADIFR :
3547c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3557c478bd9Sstevel@tonic-gate 			error = EPERM;
3567c478bd9Sstevel@tonic-gate 		else
357f4b3ec61Sdh 			error = frrequest(unit, cmd, data,
358f4b3ec61Sdh 			    1 - ifs->ifs_fr_active, 1, ifs);
3597c478bd9Sstevel@tonic-gate 		break;
3607c478bd9Sstevel@tonic-gate 	case SIOCSWAPA :
3617c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3627c478bd9Sstevel@tonic-gate 			error = EPERM;
3637c478bd9Sstevel@tonic-gate 		else {
364f4b3ec61Sdh 			*(u_int *)data = ifs->ifs_fr_active;
365f4b3ec61Sdh 			ifs->ifs_fr_active = 1 - ifs->ifs_fr_active;
3667c478bd9Sstevel@tonic-gate 		}
3677c478bd9Sstevel@tonic-gate 		break;
3687c478bd9Sstevel@tonic-gate 	case SIOCGETFS :
369f4b3ec61Sdh 		fr_getstat(&fio, ifs);
3707c478bd9Sstevel@tonic-gate 		error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT);
3717c478bd9Sstevel@tonic-gate 		break;
3727c478bd9Sstevel@tonic-gate 	case	SIOCFRZST :
3737c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3747c478bd9Sstevel@tonic-gate 			error = EPERM;
3757c478bd9Sstevel@tonic-gate 		else
376f4b3ec61Sdh 			error = frzerostats(data, ifs);
3777c478bd9Sstevel@tonic-gate 		break;
3787c478bd9Sstevel@tonic-gate 	case	SIOCIPFFL :
3797c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3807c478bd9Sstevel@tonic-gate 			error = EPERM;
3817c478bd9Sstevel@tonic-gate 		else {
3827c478bd9Sstevel@tonic-gate 			error = COPYIN(data, &tmp, sizeof(tmp));
3837c478bd9Sstevel@tonic-gate 			if (!error) {
384f4b3ec61Sdh 				tmp = frflush(unit, 4, tmp, ifs);
3857c478bd9Sstevel@tonic-gate 				error = COPYOUT(&tmp, data, sizeof(tmp));
3867c478bd9Sstevel@tonic-gate 			}
3877c478bd9Sstevel@tonic-gate 		}
3887c478bd9Sstevel@tonic-gate 		break;
3897663b816Sml #ifdef	USE_INET6
3907663b816Sml 	case	SIOCIPFL6 :
3917663b816Sml 		if (!(mode & FWRITE))
3927663b816Sml 			error = EPERM;
3937663b816Sml 		else {
3947663b816Sml 			error = COPYIN(data, &tmp, sizeof(tmp));
3957663b816Sml 			if (!error) {
396f4b3ec61Sdh 				tmp = frflush(unit, 6, tmp, ifs);
3977663b816Sml 				error = COPYOUT(&tmp, data, sizeof(tmp));
3987663b816Sml 			}
3997663b816Sml 		}
4007663b816Sml 		break;
4017663b816Sml #endif
4027c478bd9Sstevel@tonic-gate 	case SIOCSTLCK :
4037c478bd9Sstevel@tonic-gate 		error = COPYIN(data, &tmp, sizeof(tmp));
4047c478bd9Sstevel@tonic-gate 		if (error == 0) {
405f4b3ec61Sdh 			ifs->ifs_fr_state_lock = tmp;
406f4b3ec61Sdh 			ifs->ifs_fr_nat_lock = tmp;
407f4b3ec61Sdh 			ifs->ifs_fr_frag_lock = tmp;
408f4b3ec61Sdh 			ifs->ifs_fr_auth_lock = tmp;
4097c478bd9Sstevel@tonic-gate 		} else
4107c478bd9Sstevel@tonic-gate 			error = EFAULT;
4117c478bd9Sstevel@tonic-gate 		break;
4127c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_LOG
4137c478bd9Sstevel@tonic-gate 	case	SIOCIPFFB :
4147c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
4157c478bd9Sstevel@tonic-gate 			error = EPERM;
4167c478bd9Sstevel@tonic-gate 		else
417f4b3ec61Sdh 			*(int *)data = ipflog_clear(unit, ifs);
4187c478bd9Sstevel@tonic-gate 		break;
4197c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOG */
4207c478bd9Sstevel@tonic-gate 	case SIOCGFRST :
421f4b3ec61Sdh 		error = fr_outobj(data, fr_fragstats(ifs), IPFOBJ_FRAGSTAT);
4227c478bd9Sstevel@tonic-gate 		break;
4237c478bd9Sstevel@tonic-gate 	case SIOCFRSYN :
4247c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
4257c478bd9Sstevel@tonic-gate 			error = EPERM;
4267c478bd9Sstevel@tonic-gate 		else {
427f4b3ec61Sdh 			frsync(IPFSYNC_RESYNC, IPFSYNC_RESYNC, NULL, NULL, ifs);
4287c478bd9Sstevel@tonic-gate 		}
4297c478bd9Sstevel@tonic-gate 		break;
4307c478bd9Sstevel@tonic-gate 	default :
4317c478bd9Sstevel@tonic-gate 		error = EINVAL;
4327c478bd9Sstevel@tonic-gate 		break;
4337c478bd9Sstevel@tonic-gate 	}
4347c478bd9Sstevel@tonic-gate 	SPL_X(s);
4357c478bd9Sstevel@tonic-gate 	return error;
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 
fr_forgetifp(ifp,ifs)439f4b3ec61Sdh void fr_forgetifp(ifp, ifs)
4407c478bd9Sstevel@tonic-gate void *ifp;
441f4b3ec61Sdh ipf_stack_t *ifs;
4427c478bd9Sstevel@tonic-gate {
4437c478bd9Sstevel@tonic-gate 	register frentry_t *f;
4447c478bd9Sstevel@tonic-gate 
445f4b3ec61Sdh 	WRITE_ENTER(&ifs->ifs_ipf_mutex);
446f4b3ec61Sdh 	for (f = ifs->ifs_ipacct[0][ifs->ifs_fr_active]; (f != NULL);
447f4b3ec61Sdh 	    f = f->fr_next)
4487c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4497c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
450f4b3ec61Sdh 	for (f = ifs->ifs_ipacct[1][ifs->ifs_fr_active]; (f != NULL);
451f4b3ec61Sdh 	    f = f->fr_next)
4527c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4537c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
454f4b3ec61Sdh 	for (f = ifs->ifs_ipfilter[0][ifs->ifs_fr_active]; (f != NULL);
455f4b3ec61Sdh 	    f = f->fr_next)
4567c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4577c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
458f4b3ec61Sdh 	for (f = ifs->ifs_ipfilter[1][ifs->ifs_fr_active]; (f != NULL);
459f4b3ec61Sdh 	    f = f->fr_next)
4607c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4617c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4627c478bd9Sstevel@tonic-gate #ifdef	USE_INET6
463f4b3ec61Sdh 	for (f = ifs->ifs_ipacct6[0][ifs->ifs_fr_active]; (f != NULL);
464f4b3ec61Sdh 	    f = f->fr_next)
4657c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4667c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
467f4b3ec61Sdh 	for (f = ifs->ifs_ipacct6[1][ifs->ifs_fr_active]; (f != NULL);
468f4b3ec61Sdh 	    f = f->fr_next)
4697c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4707c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
471f4b3ec61Sdh 	for (f = ifs->ifs_ipfilter6[0][ifs->ifs_fr_active]; (f != NULL);
472f4b3ec61Sdh 	    f = f->fr_next)
4737c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4747c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
475f4b3ec61Sdh 	for (f = ifs->ifs_ipfilter6[1][ifs->ifs_fr_active]; (f != NULL);
476f4b3ec61Sdh 	    f = f->fr_next)
4777c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4787c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4797c478bd9Sstevel@tonic-gate #endif
480f4b3ec61Sdh 	RWLOCK_EXIT(&ifs->ifs_ipf_mutex);
481d6c23f6fSyx 	fr_natifpsync(IPFSYNC_OLDIFP, 4, ifp, NULL, ifs);
482d6c23f6fSyx 	fr_natifpsync(IPFSYNC_OLDIFP, 6, ifp, NULL, ifs);
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 
fr_resolvedest(fdp,v,ifs)486f4b3ec61Sdh void fr_resolvedest(fdp, v, ifs)
4877c478bd9Sstevel@tonic-gate frdest_t *fdp;
4887c478bd9Sstevel@tonic-gate int v;
489f4b3ec61Sdh ipf_stack_t *ifs;
4907c478bd9Sstevel@tonic-gate {
4917c478bd9Sstevel@tonic-gate 	fdp->fd_ifp = NULL;
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 	if (*fdp->fd_ifname) {
494f4b3ec61Sdh 		fdp->fd_ifp = GETIFP(fdp->fd_ifname, v, ifs);
4957c478bd9Sstevel@tonic-gate 		if (!fdp->fd_ifp)
4967c478bd9Sstevel@tonic-gate 			fdp->fd_ifp = (struct ifnet *)-1;
4977c478bd9Sstevel@tonic-gate 	}
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 
501ab25eeb5Syz #if defined(__sgi) && (IRIX < 60500)
no_output(ifp,m,s)5027c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s)
5037c478bd9Sstevel@tonic-gate #else
5047c478bd9Sstevel@tonic-gate # if TRU64 >= 1885
5057c478bd9Sstevel@tonic-gate static int no_output (ifp, m, s, rt, cp)
5067c478bd9Sstevel@tonic-gate char *cp;
5077c478bd9Sstevel@tonic-gate # else
5087c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s, rt)
5097c478bd9Sstevel@tonic-gate # endif
5107c478bd9Sstevel@tonic-gate struct rtentry *rt;
5117c478bd9Sstevel@tonic-gate #endif
5127c478bd9Sstevel@tonic-gate struct ifnet *ifp;
5137c478bd9Sstevel@tonic-gate struct mbuf *m;
5147c478bd9Sstevel@tonic-gate struct sockaddr *s;
5157c478bd9Sstevel@tonic-gate {
5167c478bd9Sstevel@tonic-gate 	return 0;
5177c478bd9Sstevel@tonic-gate }
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 
520