xref: /illumos-gate/usr/src/cmd/ipf/tools/ip_fil.c (revision 7663b816)
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  *
6*7663b816Sml  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
77c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
87c478bd9Sstevel@tonic-gate  */
97c478bd9Sstevel@tonic-gate 
107c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate #if !defined(lint)
137c478bd9Sstevel@tonic-gate static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.121 2003/06/28 17:01:55 darrenr Exp $";
147c478bd9Sstevel@tonic-gate #endif
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate #ifndef	SOLARIS
177c478bd9Sstevel@tonic-gate #define	SOLARIS	(defined(sun) && (defined(__svr4__) || defined(__SVR4)))
187c478bd9Sstevel@tonic-gate #endif
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL)
217c478bd9Sstevel@tonic-gate # undef KERNEL
227c478bd9Sstevel@tonic-gate # undef _KERNEL
237c478bd9Sstevel@tonic-gate # define        KERNEL	1
247c478bd9Sstevel@tonic-gate # define        _KERNEL	1
257c478bd9Sstevel@tonic-gate #endif
267c478bd9Sstevel@tonic-gate #include <sys/param.h>
277c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__) && !defined(__FreeBSD_version)
287c478bd9Sstevel@tonic-gate # if defined(IPFILTER_LKM)
297c478bd9Sstevel@tonic-gate #  ifndef __FreeBSD_cc_version
307c478bd9Sstevel@tonic-gate #   include <osreldate.h>
317c478bd9Sstevel@tonic-gate #  else
327c478bd9Sstevel@tonic-gate #   if __FreeBSD_cc_version < 430000
337c478bd9Sstevel@tonic-gate #    include <osreldate.h>
347c478bd9Sstevel@tonic-gate #   endif
357c478bd9Sstevel@tonic-gate #  endif
367c478bd9Sstevel@tonic-gate # endif
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate #include <sys/errno.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #ifdef _KERNEL
427c478bd9Sstevel@tonic-gate #  include <sys/systm.h>
437c478bd9Sstevel@tonic-gate #  include <sys/fcntl.h>
447c478bd9Sstevel@tonic-gate #else
457c478bd9Sstevel@tonic-gate #  define _KERNEL
467c478bd9Sstevel@tonic-gate #  ifdef __OpenBSD__
477c478bd9Sstevel@tonic-gate struct file;
487c478bd9Sstevel@tonic-gate #  endif
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #  include <sys/uio.h>
517c478bd9Sstevel@tonic-gate #  undef _KERNEL
527c478bd9Sstevel@tonic-gate #endif
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #include <sys/file.h>
557c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #include <stdio.h>
587c478bd9Sstevel@tonic-gate #include <string.h>
597c478bd9Sstevel@tonic-gate #include <stdlib.h>
607c478bd9Sstevel@tonic-gate #include <ctype.h>
617c478bd9Sstevel@tonic-gate #include <fcntl.h>
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate #ifdef __sgi
647c478bd9Sstevel@tonic-gate # include <sys/ptimers.h>
657c478bd9Sstevel@tonic-gate #endif
667c478bd9Sstevel@tonic-gate #include <sys/time.h>
677c478bd9Sstevel@tonic-gate #if !SOLARIS
687c478bd9Sstevel@tonic-gate # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
697c478bd9Sstevel@tonic-gate #  include <sys/dirent.h>
707c478bd9Sstevel@tonic-gate # else
717c478bd9Sstevel@tonic-gate #  include <sys/dir.h>
727c478bd9Sstevel@tonic-gate # endif
737c478bd9Sstevel@tonic-gate #else
747c478bd9Sstevel@tonic-gate # include <sys/filio.h>
757c478bd9Sstevel@tonic-gate #endif
767c478bd9Sstevel@tonic-gate #include <sys/protosw.h>
777c478bd9Sstevel@tonic-gate #include <sys/socket.h>
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate #include <stdio.h>
807c478bd9Sstevel@tonic-gate #include <string.h>
817c478bd9Sstevel@tonic-gate #include <stdlib.h>
827c478bd9Sstevel@tonic-gate #include <ctype.h>
837c478bd9Sstevel@tonic-gate #include <fcntl.h>
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate #ifdef __hpux
867c478bd9Sstevel@tonic-gate # define _NET_ROUTE_INCLUDED
877c478bd9Sstevel@tonic-gate #endif
887c478bd9Sstevel@tonic-gate #include <net/if.h>
897c478bd9Sstevel@tonic-gate #ifdef sun
907c478bd9Sstevel@tonic-gate # include <net/af.h>
917c478bd9Sstevel@tonic-gate #endif
927c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000
937c478bd9Sstevel@tonic-gate # include <net/if_var.h>
947c478bd9Sstevel@tonic-gate #endif
957c478bd9Sstevel@tonic-gate #ifdef __sgi
967c478bd9Sstevel@tonic-gate #include <sys/debug.h>
977c478bd9Sstevel@tonic-gate # ifdef IFF_DRVRLOCK /* IRIX6 */
987c478bd9Sstevel@tonic-gate #include <sys/hashing.h>
997c478bd9Sstevel@tonic-gate # endif
1007c478bd9Sstevel@tonic-gate #endif
1017c478bd9Sstevel@tonic-gate #include <net/route.h>
1027c478bd9Sstevel@tonic-gate #include <netinet/in.h>
1037c478bd9Sstevel@tonic-gate #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \
1047c478bd9Sstevel@tonic-gate     !defined(__hpux)
1057c478bd9Sstevel@tonic-gate # include <netinet/in_var.h>
1067c478bd9Sstevel@tonic-gate #endif
1077c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h>
1087c478bd9Sstevel@tonic-gate #include <netinet/ip.h>
1097c478bd9Sstevel@tonic-gate #include <netinet/ip_var.h>
1107c478bd9Sstevel@tonic-gate #include <netinet/tcp.h>
1117c478bd9Sstevel@tonic-gate #if defined(__osf__)
1127c478bd9Sstevel@tonic-gate # include <netinet/tcp_timer.h>
1137c478bd9Sstevel@tonic-gate #endif
1147c478bd9Sstevel@tonic-gate #include <netinet/udp.h>
1157c478bd9Sstevel@tonic-gate #include <netinet/tcpip.h>
1167c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h>
1177c478bd9Sstevel@tonic-gate #include <unistd.h>
1187c478bd9Sstevel@tonic-gate #include <syslog.h>
1197c478bd9Sstevel@tonic-gate #ifdef __hpux
1207c478bd9Sstevel@tonic-gate # undef _NET_ROUTE_INCLUDED
1217c478bd9Sstevel@tonic-gate #endif
1227c478bd9Sstevel@tonic-gate #if SOLARIS2 >= 10
1237c478bd9Sstevel@tonic-gate #include "ip_compat.h"
1247c478bd9Sstevel@tonic-gate #include "ip_fil.h"
1257c478bd9Sstevel@tonic-gate #include "ip_nat.h"
1267c478bd9Sstevel@tonic-gate #include "ip_frag.h"
1277c478bd9Sstevel@tonic-gate #include "ip_state.h"
1287c478bd9Sstevel@tonic-gate #include "ip_proxy.h"
1297c478bd9Sstevel@tonic-gate #include "ip_auth.h"
1307c478bd9Sstevel@tonic-gate #else
1317c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h"
1327c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h"
1337c478bd9Sstevel@tonic-gate #include "netinet/ip_nat.h"
1347c478bd9Sstevel@tonic-gate #include "netinet/ip_frag.h"
1357c478bd9Sstevel@tonic-gate #include "netinet/ip_state.h"
1367c478bd9Sstevel@tonic-gate #include "netinet/ip_proxy.h"
1377c478bd9Sstevel@tonic-gate #include "netinet/ip_auth.h"
1387c478bd9Sstevel@tonic-gate #endif
1397c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SYNC
1407c478bd9Sstevel@tonic-gate #include "netinet/ip_sync.h"
1417c478bd9Sstevel@tonic-gate #endif
1427c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SCAN
1437c478bd9Sstevel@tonic-gate #include "netinet/ip_scan.h"
1447c478bd9Sstevel@tonic-gate #endif
1457c478bd9Sstevel@tonic-gate #if SOLARIS2 >= 10
1467c478bd9Sstevel@tonic-gate #include "ip_pool.h"
1477c478bd9Sstevel@tonic-gate #else
1487c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h"
1497c478bd9Sstevel@tonic-gate #endif
1507c478bd9Sstevel@tonic-gate #ifdef IPFILTER_COMPILED
1517c478bd9Sstevel@tonic-gate # include "netinet/ip_rules.h"
1527c478bd9Sstevel@tonic-gate #endif
1537c478bd9Sstevel@tonic-gate #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
1547c478bd9Sstevel@tonic-gate # include <sys/malloc.h>
1557c478bd9Sstevel@tonic-gate #endif
1567c478bd9Sstevel@tonic-gate #ifdef __hpux
1577c478bd9Sstevel@tonic-gate struct rtentry;
1587c478bd9Sstevel@tonic-gate #endif
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate #include <sys/md5.h>
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate #if !defined(__osf__)
1637c478bd9Sstevel@tonic-gate extern	struct	protosw	inetsw[];
1647c478bd9Sstevel@tonic-gate #endif
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate #include "ipt.h"
1677c478bd9Sstevel@tonic-gate static	struct	ifnet **ifneta = NULL;
1687c478bd9Sstevel@tonic-gate static	int	nifs = 0;
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate static	int	frzerostats __P((caddr_t));
1717c478bd9Sstevel@tonic-gate void	init_ifp __P((void));
1727c478bd9Sstevel@tonic-gate #if defined(__sgi) && (IRIX < 605)
1737c478bd9Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1747c478bd9Sstevel@tonic-gate 			       struct sockaddr *));
1757c478bd9Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1767c478bd9Sstevel@tonic-gate 				  struct sockaddr *));
1777c478bd9Sstevel@tonic-gate #else
1787c478bd9Sstevel@tonic-gate # if TRU64 >= 1885
1797c478bd9Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1807c478bd9Sstevel@tonic-gate 			       struct sockaddr *, struct rtentry *, char *));
1817c478bd9Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1827c478bd9Sstevel@tonic-gate 				  struct sockaddr *, struct rtentry *, char *));
1837c478bd9Sstevel@tonic-gate # else
1847c478bd9Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1857c478bd9Sstevel@tonic-gate 			       struct sockaddr *, struct rtentry *));
1867c478bd9Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1877c478bd9Sstevel@tonic-gate 				  struct sockaddr *, struct rtentry *));
1887c478bd9Sstevel@tonic-gate # endif
1897c478bd9Sstevel@tonic-gate #endif
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate int iplattach()
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate 	fr_running = 1;
1957c478bd9Sstevel@tonic-gate 	return 0;
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate int ipldetach()
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate 	fr_running = -1;
2027c478bd9Sstevel@tonic-gate 	return 0;
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate static	int	frzerostats(data)
2077c478bd9Sstevel@tonic-gate caddr_t	data;
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate 	friostat_t fio;
2107c478bd9Sstevel@tonic-gate 	int error;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	fr_getstat(&fio);
2137c478bd9Sstevel@tonic-gate 	error = copyoutptr(&fio, data, sizeof(fio));
2147c478bd9Sstevel@tonic-gate 	if (error)
2157c478bd9Sstevel@tonic-gate 		return EFAULT;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	bzero((char *)frstats, sizeof(*frstats) * 2);
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	return 0;
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate /*
2257c478bd9Sstevel@tonic-gate  * Filter ioctl interface.
2267c478bd9Sstevel@tonic-gate  */
2277c478bd9Sstevel@tonic-gate int iplioctl(dev, cmd, data, mode)
2287c478bd9Sstevel@tonic-gate int dev;
2297c478bd9Sstevel@tonic-gate #if defined(__NetBSD__) || defined(__OpenBSD__) || \
2307c478bd9Sstevel@tonic-gate 	(_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
2317c478bd9Sstevel@tonic-gate u_long cmd;
2327c478bd9Sstevel@tonic-gate #else
2337c478bd9Sstevel@tonic-gate int cmd;
2347c478bd9Sstevel@tonic-gate #endif
2357c478bd9Sstevel@tonic-gate caddr_t data;
2367c478bd9Sstevel@tonic-gate int mode;
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate 	int error = 0, unit = 0, tmp;
2397c478bd9Sstevel@tonic-gate 	friostat_t fio;
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	unit = dev;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	SPL_NET(s);
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGNAT) {
2467c478bd9Sstevel@tonic-gate 		if (fr_running > 0)
2477c478bd9Sstevel@tonic-gate 			error = fr_nat_ioctl(data, cmd, mode);
2487c478bd9Sstevel@tonic-gate 		else
2497c478bd9Sstevel@tonic-gate 			error = EIO;
2507c478bd9Sstevel@tonic-gate 		SPL_X(s);
2517c478bd9Sstevel@tonic-gate 		return error;
2527c478bd9Sstevel@tonic-gate 	}
2537c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGSTATE) {
2547c478bd9Sstevel@tonic-gate 		if (fr_running > 0)
2557c478bd9Sstevel@tonic-gate 			error = fr_state_ioctl(data, cmd, mode);
2567c478bd9Sstevel@tonic-gate 		else
2577c478bd9Sstevel@tonic-gate 			error = EIO;
2587c478bd9Sstevel@tonic-gate 		SPL_X(s);
2597c478bd9Sstevel@tonic-gate 		return error;
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGAUTH) {
2627c478bd9Sstevel@tonic-gate 		if (fr_running > 0) {
2637c478bd9Sstevel@tonic-gate 			if ((cmd == SIOCADAFR) || (cmd == SIOCRMAFR)) {
2647c478bd9Sstevel@tonic-gate 				if (!(mode & FWRITE)) {
2657c478bd9Sstevel@tonic-gate 					error = EPERM;
2667c478bd9Sstevel@tonic-gate 				} else {
2677c478bd9Sstevel@tonic-gate 					error = frrequest(unit, cmd, data,
2687c478bd9Sstevel@tonic-gate 							  fr_active, 1);
2697c478bd9Sstevel@tonic-gate 				}
2707c478bd9Sstevel@tonic-gate 			} else {
2717c478bd9Sstevel@tonic-gate 				error = fr_auth_ioctl(data, mode, cmd);
2727c478bd9Sstevel@tonic-gate 			}
2737c478bd9Sstevel@tonic-gate 		} else
2747c478bd9Sstevel@tonic-gate 			error = EIO;
2757c478bd9Sstevel@tonic-gate 		SPL_X(s);
2767c478bd9Sstevel@tonic-gate 		return error;
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGSYNC) {
2797c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SYNC
2807c478bd9Sstevel@tonic-gate 		if (fr_running > 0)
2817c478bd9Sstevel@tonic-gate 			error = fr_sync_ioctl(data, cmd, mode);
2827c478bd9Sstevel@tonic-gate 		else
2837c478bd9Sstevel@tonic-gate #endif
2847c478bd9Sstevel@tonic-gate 			error = EIO;
2857c478bd9Sstevel@tonic-gate 		SPL_X(s);
2867c478bd9Sstevel@tonic-gate 		return error;
2877c478bd9Sstevel@tonic-gate 	}
2887c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGSCAN) {
2897c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_SCAN
2907c478bd9Sstevel@tonic-gate 		if (fr_running > 0)
2917c478bd9Sstevel@tonic-gate 			error = fr_scan_ioctl(data, cmd, mode);
2927c478bd9Sstevel@tonic-gate 		else
2937c478bd9Sstevel@tonic-gate #endif
2947c478bd9Sstevel@tonic-gate 			error = EIO;
2957c478bd9Sstevel@tonic-gate 		SPL_X(s);
2967c478bd9Sstevel@tonic-gate 		return error;
2977c478bd9Sstevel@tonic-gate 	}
2987c478bd9Sstevel@tonic-gate 	if (unit == IPL_LOGLOOKUP) {
2997c478bd9Sstevel@tonic-gate 		if (fr_running > 0)
3007c478bd9Sstevel@tonic-gate 			error = ip_lookup_ioctl(data, cmd, mode);
3017c478bd9Sstevel@tonic-gate 		else
3027c478bd9Sstevel@tonic-gate 			error = EIO;
3037c478bd9Sstevel@tonic-gate 		SPL_X(s);
3047c478bd9Sstevel@tonic-gate 		return error;
3057c478bd9Sstevel@tonic-gate 	}
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	switch (cmd)
3087c478bd9Sstevel@tonic-gate 	{
3097c478bd9Sstevel@tonic-gate 	case FIONREAD :
3107c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOG
3117c478bd9Sstevel@tonic-gate 		error = COPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data,
3127c478bd9Sstevel@tonic-gate 			       sizeof(iplused[IPL_LOGIPF]));
3137c478bd9Sstevel@tonic-gate #endif
3147c478bd9Sstevel@tonic-gate 		break;
3157c478bd9Sstevel@tonic-gate 	case SIOCFRENB :
3167c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3177c478bd9Sstevel@tonic-gate 			error = EPERM;
3187c478bd9Sstevel@tonic-gate 		else {
3197c478bd9Sstevel@tonic-gate 			error = COPYIN(data, &tmp, sizeof(tmp));
3207c478bd9Sstevel@tonic-gate 			if (error)
3217c478bd9Sstevel@tonic-gate 				break;
3227c478bd9Sstevel@tonic-gate 			if (tmp)
3237c478bd9Sstevel@tonic-gate 				error = iplattach();
3247c478bd9Sstevel@tonic-gate 			else
3257c478bd9Sstevel@tonic-gate 				error = ipldetach();
3267c478bd9Sstevel@tonic-gate 		}
3277c478bd9Sstevel@tonic-gate 		break;
3287c478bd9Sstevel@tonic-gate 	case SIOCSETFF :
3297c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3307c478bd9Sstevel@tonic-gate 			error = EPERM;
3317c478bd9Sstevel@tonic-gate 		else
3327c478bd9Sstevel@tonic-gate 			error = COPYIN(data, &fr_flags, sizeof(fr_flags));
3337c478bd9Sstevel@tonic-gate 		break;
3347c478bd9Sstevel@tonic-gate 	case SIOCGETFF :
3357c478bd9Sstevel@tonic-gate 		error = COPYOUT(&fr_flags, data, sizeof(fr_flags));
3367c478bd9Sstevel@tonic-gate 		break;
3377c478bd9Sstevel@tonic-gate 	case SIOCFUNCL :
3387c478bd9Sstevel@tonic-gate 		error = fr_resolvefunc(data);
3397c478bd9Sstevel@tonic-gate 		break;
3407c478bd9Sstevel@tonic-gate 	case SIOCINAFR :
3417c478bd9Sstevel@tonic-gate 	case SIOCRMAFR :
3427c478bd9Sstevel@tonic-gate 	case SIOCADAFR :
3437c478bd9Sstevel@tonic-gate 	case SIOCZRLST :
3447c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3457c478bd9Sstevel@tonic-gate 			error = EPERM;
3467c478bd9Sstevel@tonic-gate 		else
3477c478bd9Sstevel@tonic-gate 			error = frrequest(unit, cmd, data, fr_active, 1);
3487c478bd9Sstevel@tonic-gate 		break;
3497c478bd9Sstevel@tonic-gate 	case SIOCINIFR :
3507c478bd9Sstevel@tonic-gate 	case SIOCRMIFR :
3517c478bd9Sstevel@tonic-gate 	case SIOCADIFR :
3527c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3537c478bd9Sstevel@tonic-gate 			error = EPERM;
3547c478bd9Sstevel@tonic-gate 		else
3557c478bd9Sstevel@tonic-gate 			error = frrequest(unit, cmd, data, 1 - fr_active, 1);
3567c478bd9Sstevel@tonic-gate 		break;
3577c478bd9Sstevel@tonic-gate 	case SIOCSWAPA :
3587c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3597c478bd9Sstevel@tonic-gate 			error = EPERM;
3607c478bd9Sstevel@tonic-gate 		else {
3617c478bd9Sstevel@tonic-gate 			bzero((char *)frcache, sizeof(frcache[0]) * 2);
3627c478bd9Sstevel@tonic-gate 			*(u_int *)data = fr_active;
3637c478bd9Sstevel@tonic-gate 			fr_active = 1 - fr_active;
3647c478bd9Sstevel@tonic-gate 		}
3657c478bd9Sstevel@tonic-gate 		break;
3667c478bd9Sstevel@tonic-gate 	case SIOCGETFS :
3677c478bd9Sstevel@tonic-gate 		fr_getstat(&fio);
3687c478bd9Sstevel@tonic-gate 		error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT);
3697c478bd9Sstevel@tonic-gate 		break;
3707c478bd9Sstevel@tonic-gate 	case	SIOCFRZST :
3717c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3727c478bd9Sstevel@tonic-gate 			error = EPERM;
3737c478bd9Sstevel@tonic-gate 		else
3747c478bd9Sstevel@tonic-gate 			error = frzerostats(data);
3757c478bd9Sstevel@tonic-gate 		break;
3767c478bd9Sstevel@tonic-gate 	case	SIOCIPFFL :
3777c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
3787c478bd9Sstevel@tonic-gate 			error = EPERM;
3797c478bd9Sstevel@tonic-gate 		else {
3807c478bd9Sstevel@tonic-gate 			error = COPYIN(data, &tmp, sizeof(tmp));
3817c478bd9Sstevel@tonic-gate 			if (!error) {
382*7663b816Sml 				tmp = frflush(unit, 4, tmp);
3837c478bd9Sstevel@tonic-gate 				error = COPYOUT(&tmp, data, sizeof(tmp));
3847c478bd9Sstevel@tonic-gate 			}
3857c478bd9Sstevel@tonic-gate 		}
3867c478bd9Sstevel@tonic-gate 		break;
387*7663b816Sml #ifdef	USE_INET6
388*7663b816Sml 	case	SIOCIPFL6 :
389*7663b816Sml 		if (!(mode & FWRITE))
390*7663b816Sml 			error = EPERM;
391*7663b816Sml 		else {
392*7663b816Sml 			error = COPYIN(data, &tmp, sizeof(tmp));
393*7663b816Sml 			if (!error) {
394*7663b816Sml 				tmp = frflush(unit, 6, tmp);
395*7663b816Sml 				error = COPYOUT(&tmp, data, sizeof(tmp));
396*7663b816Sml 			}
397*7663b816Sml 		}
398*7663b816Sml 		break;
399*7663b816Sml #endif
4007c478bd9Sstevel@tonic-gate 	case SIOCSTLCK :
4017c478bd9Sstevel@tonic-gate 		error = COPYIN(data, &tmp, sizeof(tmp));
4027c478bd9Sstevel@tonic-gate 		if (error == 0) {
4037c478bd9Sstevel@tonic-gate 			fr_state_lock = tmp;
4047c478bd9Sstevel@tonic-gate 			fr_nat_lock = tmp;
4057c478bd9Sstevel@tonic-gate 			fr_frag_lock = tmp;
4067c478bd9Sstevel@tonic-gate 			fr_auth_lock = tmp;
4077c478bd9Sstevel@tonic-gate 		} else
4087c478bd9Sstevel@tonic-gate 			error = EFAULT;
4097c478bd9Sstevel@tonic-gate 		break;
4107c478bd9Sstevel@tonic-gate #ifdef	IPFILTER_LOG
4117c478bd9Sstevel@tonic-gate 	case	SIOCIPFFB :
4127c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
4137c478bd9Sstevel@tonic-gate 			error = EPERM;
4147c478bd9Sstevel@tonic-gate 		else
4157c478bd9Sstevel@tonic-gate 			*(int *)data = ipflog_clear(unit);
4167c478bd9Sstevel@tonic-gate 		break;
4177c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOG */
4187c478bd9Sstevel@tonic-gate 	case SIOCGFRST :
4197c478bd9Sstevel@tonic-gate 		error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT);
4207c478bd9Sstevel@tonic-gate 		break;
4217c478bd9Sstevel@tonic-gate 	case SIOCFRSYN :
4227c478bd9Sstevel@tonic-gate 		if (!(mode & FWRITE))
4237c478bd9Sstevel@tonic-gate 			error = EPERM;
4247c478bd9Sstevel@tonic-gate 		else {
4257c478bd9Sstevel@tonic-gate 			frsync();
4267c478bd9Sstevel@tonic-gate 		}
4277c478bd9Sstevel@tonic-gate 		break;
4287c478bd9Sstevel@tonic-gate 	default :
4297c478bd9Sstevel@tonic-gate 		error = EINVAL;
4307c478bd9Sstevel@tonic-gate 		break;
4317c478bd9Sstevel@tonic-gate 	}
4327c478bd9Sstevel@tonic-gate 	SPL_X(s);
4337c478bd9Sstevel@tonic-gate 	return error;
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate void fr_forgetifp(ifp)
4387c478bd9Sstevel@tonic-gate void *ifp;
4397c478bd9Sstevel@tonic-gate {
4407c478bd9Sstevel@tonic-gate 	register frentry_t *f;
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	WRITE_ENTER(&ipf_mutex);
4437c478bd9Sstevel@tonic-gate 	for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next)
4447c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4457c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4467c478bd9Sstevel@tonic-gate 	for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next)
4477c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4487c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4497c478bd9Sstevel@tonic-gate 	for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next)
4507c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4517c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4527c478bd9Sstevel@tonic-gate 	for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next)
4537c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4547c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4557c478bd9Sstevel@tonic-gate #ifdef	USE_INET6
4567c478bd9Sstevel@tonic-gate 	for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next)
4577c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4587c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4597c478bd9Sstevel@tonic-gate 	for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next)
4607c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4617c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4627c478bd9Sstevel@tonic-gate 	for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next)
4637c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4647c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4657c478bd9Sstevel@tonic-gate 	for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next)
4667c478bd9Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4677c478bd9Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4687c478bd9Sstevel@tonic-gate #endif
4697c478bd9Sstevel@tonic-gate 	RWLOCK_EXIT(&ipf_mutex);
4707c478bd9Sstevel@tonic-gate 	fr_natsync(ifp);
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate void fr_resolvdest(fdp, v)
4757c478bd9Sstevel@tonic-gate frdest_t *fdp;
4767c478bd9Sstevel@tonic-gate int v;
4777c478bd9Sstevel@tonic-gate {
4787c478bd9Sstevel@tonic-gate 	fdp->fd_ifp = NULL;
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	if (*fdp->fd_ifname) {
4817c478bd9Sstevel@tonic-gate 		fdp->fd_ifp = GETIFP(fdp->fd_ifname, v);
4827c478bd9Sstevel@tonic-gate 		if (!fdp->fd_ifp)
4837c478bd9Sstevel@tonic-gate 			fdp->fd_ifp = (struct ifnet *)-1;
4847c478bd9Sstevel@tonic-gate 	}
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate #if defined(__sgi) && (IRIX < 605)
4897c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s)
4907c478bd9Sstevel@tonic-gate #else
4917c478bd9Sstevel@tonic-gate # if TRU64 >= 1885
4927c478bd9Sstevel@tonic-gate static int no_output (ifp, m, s, rt, cp)
4937c478bd9Sstevel@tonic-gate char *cp;
4947c478bd9Sstevel@tonic-gate # else
4957c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s, rt)
4967c478bd9Sstevel@tonic-gate # endif
4977c478bd9Sstevel@tonic-gate struct rtentry *rt;
4987c478bd9Sstevel@tonic-gate #endif
4997c478bd9Sstevel@tonic-gate struct ifnet *ifp;
5007c478bd9Sstevel@tonic-gate struct mbuf *m;
5017c478bd9Sstevel@tonic-gate struct sockaddr *s;
5027c478bd9Sstevel@tonic-gate {
5037c478bd9Sstevel@tonic-gate 	return 0;
5047c478bd9Sstevel@tonic-gate }
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate #if defined(__sgi) && (IRIX < 605)
5087c478bd9Sstevel@tonic-gate static int write_output(ifp, m, s)
5097c478bd9Sstevel@tonic-gate #else
5107c478bd9Sstevel@tonic-gate # if TRU64 >= 1885
5117c478bd9Sstevel@tonic-gate static int write_output (ifp, m, s, rt, cp)
5127c478bd9Sstevel@tonic-gate char *cp;
5137c478bd9Sstevel@tonic-gate # else
5147c478bd9Sstevel@tonic-gate static int write_output(ifp, m, s, rt)
5157c478bd9Sstevel@tonic-gate # endif
5167c478bd9Sstevel@tonic-gate struct rtentry *rt;
5177c478bd9Sstevel@tonic-gate #endif
5187c478bd9Sstevel@tonic-gate struct ifnet *ifp;
5197c478bd9Sstevel@tonic-gate struct mbuf *m;
5207c478bd9Sstevel@tonic-gate struct sockaddr *s;
5217c478bd9Sstevel@tonic-gate {
5227c478bd9Sstevel@tonic-gate 	char fname[32];
5237c478bd9Sstevel@tonic-gate 	mb_t *mb;
5247c478bd9Sstevel@tonic-gate 	ip_t *ip;
5257c478bd9Sstevel@tonic-gate 	int fd;
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	mb = (mb_t *)m;
5287c478bd9Sstevel@tonic-gate 	ip = MTOD(mb, ip_t *);
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
5317c478bd9Sstevel@tonic-gate 	(defined(OpenBSD) && (OpenBSD >= 199603))
5327c478bd9Sstevel@tonic-gate 	sprintf(fname, "/tmp/%s", ifp->if_xname);
5337c478bd9Sstevel@tonic-gate #else
5347c478bd9Sstevel@tonic-gate 	sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
5357c478bd9Sstevel@tonic-gate #endif
5367c478bd9Sstevel@tonic-gate 	fd = open(fname, O_WRONLY|O_APPEND);
5377c478bd9Sstevel@tonic-gate 	if (fd == -1) {
5387c478bd9Sstevel@tonic-gate 		perror("open");
5397c478bd9Sstevel@tonic-gate 		return -1;
5407c478bd9Sstevel@tonic-gate 	}
5417c478bd9Sstevel@tonic-gate 	write(fd, (char *)ip, ntohs(ip->ip_len));
5427c478bd9Sstevel@tonic-gate 	close(fd);
5437c478bd9Sstevel@tonic-gate 	return 0;
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate struct ifnet *get_unit(name, v)
5487c478bd9Sstevel@tonic-gate char *name;
5497c478bd9Sstevel@tonic-gate int v;
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	struct ifnet *ifp, **ifa, **old_ifneta;
5527c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
5537c478bd9Sstevel@tonic-gate 	(defined(OpenBSD) && (OpenBSD >= 199603))
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	if (name == NULL)
5567c478bd9Sstevel@tonic-gate 		name = "anon0";
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
5597c478bd9Sstevel@tonic-gate 		if (!strcmp(name, ifp->if_xname))
5607c478bd9Sstevel@tonic-gate 			return ifp;
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate #else
5637c478bd9Sstevel@tonic-gate 	char *s, ifname[LIFNAMSIZ+1];
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate 	if (name == NULL)
5667c478bd9Sstevel@tonic-gate 		name = "anon0";
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 	for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
5697c478bd9Sstevel@tonic-gate 		COPYIFNAME(ifp, ifname);
5707c478bd9Sstevel@tonic-gate 		if (!strcmp(name, ifname))
5717c478bd9Sstevel@tonic-gate 			return ifp;
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate #endif
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 	if (!ifneta) {
5767c478bd9Sstevel@tonic-gate 		ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
5777c478bd9Sstevel@tonic-gate 		if (!ifneta)
5787c478bd9Sstevel@tonic-gate 			return NULL;
5797c478bd9Sstevel@tonic-gate 		ifneta[1] = NULL;
5807c478bd9Sstevel@tonic-gate 		ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
5817c478bd9Sstevel@tonic-gate 		if (!ifneta[0]) {
5827c478bd9Sstevel@tonic-gate 			free(ifneta);
5837c478bd9Sstevel@tonic-gate 			return NULL;
5847c478bd9Sstevel@tonic-gate 		}
5857c478bd9Sstevel@tonic-gate 		nifs = 1;
5867c478bd9Sstevel@tonic-gate 	} else {
5877c478bd9Sstevel@tonic-gate 		old_ifneta = ifneta;
5887c478bd9Sstevel@tonic-gate 		nifs++;
5897c478bd9Sstevel@tonic-gate 		ifneta = (struct ifnet **)realloc(ifneta,
5907c478bd9Sstevel@tonic-gate 						  (nifs + 1) * sizeof(*ifa));
5917c478bd9Sstevel@tonic-gate 		if (!ifneta) {
5927c478bd9Sstevel@tonic-gate 			free(old_ifneta);
5937c478bd9Sstevel@tonic-gate 			nifs = 0;
5947c478bd9Sstevel@tonic-gate 			return NULL;
5957c478bd9Sstevel@tonic-gate 		}
5967c478bd9Sstevel@tonic-gate 		ifneta[nifs] = NULL;
5977c478bd9Sstevel@tonic-gate 		ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
5987c478bd9Sstevel@tonic-gate 		if (!ifneta[nifs - 1]) {
5997c478bd9Sstevel@tonic-gate 			nifs--;
6007c478bd9Sstevel@tonic-gate 			return NULL;
6017c478bd9Sstevel@tonic-gate 		}
6027c478bd9Sstevel@tonic-gate 	}
6037c478bd9Sstevel@tonic-gate 	ifp = ifneta[nifs - 1];
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
6067c478bd9Sstevel@tonic-gate 	(defined(OpenBSD) && (OpenBSD >= 199603))
6077c478bd9Sstevel@tonic-gate 	strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
6087c478bd9Sstevel@tonic-gate #else
6097c478bd9Sstevel@tonic-gate 	for (s = name; *s && !isdigit(*s); s++)
6107c478bd9Sstevel@tonic-gate 		;
6117c478bd9Sstevel@tonic-gate 	if (*s && isdigit(*s)) {
6127c478bd9Sstevel@tonic-gate 		ifp->if_unit = atoi(s);
6137c478bd9Sstevel@tonic-gate 		ifp->if_name = (char *)malloc(s - name + 1);
6147c478bd9Sstevel@tonic-gate 		strncpy(ifp->if_name, name, s - name);
6157c478bd9Sstevel@tonic-gate 		ifp->if_name[s - name] = '\0';
6167c478bd9Sstevel@tonic-gate 	} else {
6177c478bd9Sstevel@tonic-gate 		ifp->if_name = strdup(name);
6187c478bd9Sstevel@tonic-gate 		ifp->if_unit = -1;
6197c478bd9Sstevel@tonic-gate 	}
6207c478bd9Sstevel@tonic-gate #endif
6217c478bd9Sstevel@tonic-gate 	ifp->if_output = no_output;
6227c478bd9Sstevel@tonic-gate 	return ifp;
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate char *get_ifname(ifp)
6277c478bd9Sstevel@tonic-gate struct ifnet *ifp;
6287c478bd9Sstevel@tonic-gate {
6297c478bd9Sstevel@tonic-gate 	static char ifname[LIFNAMSIZ];
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate #if defined(__OpenBSD__) || defined(__NetBSD__)
6327c478bd9Sstevel@tonic-gate 	sprintf(ifname, "%s", ifp->if_xname);
6337c478bd9Sstevel@tonic-gate #else
6347c478bd9Sstevel@tonic-gate 	sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
6357c478bd9Sstevel@tonic-gate #endif
6367c478bd9Sstevel@tonic-gate 	return ifname;
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate void init_ifp()
6427c478bd9Sstevel@tonic-gate {
6437c478bd9Sstevel@tonic-gate 	struct ifnet *ifp, **ifa;
6447c478bd9Sstevel@tonic-gate 	char fname[32];
6457c478bd9Sstevel@tonic-gate 	int fd;
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
6487c478bd9Sstevel@tonic-gate 	(defined(OpenBSD) && (OpenBSD >= 199603))
6497c478bd9Sstevel@tonic-gate 	for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
6507c478bd9Sstevel@tonic-gate 		ifp->if_output = write_output;
6517c478bd9Sstevel@tonic-gate 		sprintf(fname, "/tmp/%s", ifp->if_xname);
6527c478bd9Sstevel@tonic-gate 		fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
6537c478bd9Sstevel@tonic-gate 		if (fd == -1)
6547c478bd9Sstevel@tonic-gate 			perror("open");
6557c478bd9Sstevel@tonic-gate 		else
6567c478bd9Sstevel@tonic-gate 			close(fd);
6577c478bd9Sstevel@tonic-gate 	}
6587c478bd9Sstevel@tonic-gate #else
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
6617c478bd9Sstevel@tonic-gate 		ifp->if_output = write_output;
6627c478bd9Sstevel@tonic-gate 		sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
6637c478bd9Sstevel@tonic-gate 		fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
6647c478bd9Sstevel@tonic-gate 		if (fd == -1)
6657c478bd9Sstevel@tonic-gate 			perror("open");
6667c478bd9Sstevel@tonic-gate 		else
6677c478bd9Sstevel@tonic-gate 			close(fd);
6687c478bd9Sstevel@tonic-gate 	}
6697c478bd9Sstevel@tonic-gate #endif
6707c478bd9Sstevel@tonic-gate }
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate int fr_fastroute(m, mpp, fin, fdp)
6747c478bd9Sstevel@tonic-gate mb_t *m, **mpp;
6757c478bd9Sstevel@tonic-gate fr_info_t *fin;
6767c478bd9Sstevel@tonic-gate frdest_t *fdp;
6777c478bd9Sstevel@tonic-gate {
6787c478bd9Sstevel@tonic-gate 	struct ifnet *ifp = fdp->fd_ifp;
6797c478bd9Sstevel@tonic-gate 	ip_t *ip = fin->fin_ip;
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	if (!ifp)
6827c478bd9Sstevel@tonic-gate 		return 0;	/* no routing table out here */
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	ip->ip_len = htons((u_short)ip->ip_len);
6857c478bd9Sstevel@tonic-gate 	ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
6867c478bd9Sstevel@tonic-gate 	ip->ip_sum = 0;
6877c478bd9Sstevel@tonic-gate #if defined(__sgi) && (IRIX < 605)
6887c478bd9Sstevel@tonic-gate 	(*ifp->if_output)(ifp, (void *)ip, NULL);
6897c478bd9Sstevel@tonic-gate # if TRU64 >= 1885
6907c478bd9Sstevel@tonic-gate 	(*ifp->if_output)(ifp, (void *)m, NULL, 0, 0);
6917c478bd9Sstevel@tonic-gate # else
6927c478bd9Sstevel@tonic-gate 	(*ifp->if_output)(ifp, (void *)m, NULL, 0);
6937c478bd9Sstevel@tonic-gate # endif
6947c478bd9Sstevel@tonic-gate #endif
6957c478bd9Sstevel@tonic-gate 	return 0;
6967c478bd9Sstevel@tonic-gate }
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate int fr_send_reset(fin)
7007c478bd9Sstevel@tonic-gate fr_info_t *fin;
7017c478bd9Sstevel@tonic-gate {
7027c478bd9Sstevel@tonic-gate 	verbose("- TCP RST sent\n");
7037c478bd9Sstevel@tonic-gate 	return 0;
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate int fr_send_icmp_err(type, fin, dst)
7087c478bd9Sstevel@tonic-gate int type;
7097c478bd9Sstevel@tonic-gate fr_info_t *fin;
7107c478bd9Sstevel@tonic-gate int dst;
7117c478bd9Sstevel@tonic-gate {
7127c478bd9Sstevel@tonic-gate 	verbose("- TCP RST sent\n");
7137c478bd9Sstevel@tonic-gate 	return 0;
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate void frsync()
7187c478bd9Sstevel@tonic-gate {
7197c478bd9Sstevel@tonic-gate 	return;
7207c478bd9Sstevel@tonic-gate }
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate void m_freem(m)
7247c478bd9Sstevel@tonic-gate mb_t *m;
7257c478bd9Sstevel@tonic-gate {
7267c478bd9Sstevel@tonic-gate 	return;
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate void m_copydata(m, off, len, cp)
7317c478bd9Sstevel@tonic-gate mb_t *m;
7327c478bd9Sstevel@tonic-gate int off, len;
7337c478bd9Sstevel@tonic-gate caddr_t cp;
7347c478bd9Sstevel@tonic-gate {
7357c478bd9Sstevel@tonic-gate 	bcopy((char *)m + off, cp, len);
7367c478bd9Sstevel@tonic-gate }
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 
7397c478bd9Sstevel@tonic-gate int ipfuiomove(buf, len, rwflag, uio)
7407c478bd9Sstevel@tonic-gate caddr_t buf;
7417c478bd9Sstevel@tonic-gate int len, rwflag;
7427c478bd9Sstevel@tonic-gate struct uio *uio;
7437c478bd9Sstevel@tonic-gate {
7447c478bd9Sstevel@tonic-gate 	int left, ioc, num, offset;
7457c478bd9Sstevel@tonic-gate 	struct iovec *io;
7467c478bd9Sstevel@tonic-gate 	char *start;
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 	if (rwflag == UIO_READ) {
7497c478bd9Sstevel@tonic-gate 		left = len;
7507c478bd9Sstevel@tonic-gate 		ioc = 0;
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 		offset = uio->uio_offset;
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate 		while ((left > 0) && (ioc < uio->uio_iovcnt)) {
7557c478bd9Sstevel@tonic-gate 			io = uio->uio_iov + ioc;
7567c478bd9Sstevel@tonic-gate 			num = io->iov_len;
7577c478bd9Sstevel@tonic-gate 			if (num > left)
7587c478bd9Sstevel@tonic-gate 				num = left;
7597c478bd9Sstevel@tonic-gate 			start = (char *)io->iov_base + offset;
7607c478bd9Sstevel@tonic-gate 			if (start > (char *)io->iov_base + io->iov_len) {
7617c478bd9Sstevel@tonic-gate 				offset -= io->iov_len;
7627c478bd9Sstevel@tonic-gate 				ioc++;
7637c478bd9Sstevel@tonic-gate 				continue;
7647c478bd9Sstevel@tonic-gate 			}
7657c478bd9Sstevel@tonic-gate 			bcopy(buf, start, num);
7667c478bd9Sstevel@tonic-gate 			uio->uio_resid -= num;
7677c478bd9Sstevel@tonic-gate 			uio->uio_offset += num;
7687c478bd9Sstevel@tonic-gate 			left -= num;
7697c478bd9Sstevel@tonic-gate 			if (left > 0)
7707c478bd9Sstevel@tonic-gate 				ioc++;
7717c478bd9Sstevel@tonic-gate 		}
7727c478bd9Sstevel@tonic-gate 		if (left > 0)
7737c478bd9Sstevel@tonic-gate 			return EFAULT;
7747c478bd9Sstevel@tonic-gate 	}
7757c478bd9Sstevel@tonic-gate 	return 0;
7767c478bd9Sstevel@tonic-gate }
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate u_32_t fr_newisn(fin)
7807c478bd9Sstevel@tonic-gate fr_info_t *fin;
7817c478bd9Sstevel@tonic-gate {
7827c478bd9Sstevel@tonic-gate 	static int iss_seq_off = 0;
7837c478bd9Sstevel@tonic-gate 	u_char hash[16];
7847c478bd9Sstevel@tonic-gate 	u_32_t newiss;
7857c478bd9Sstevel@tonic-gate 	MD5_CTX ctx;
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	/*
7887c478bd9Sstevel@tonic-gate 	 * Compute the base value of the ISS.  It is a hash
7897c478bd9Sstevel@tonic-gate 	 * of (saddr, sport, daddr, dport, secret).
7907c478bd9Sstevel@tonic-gate 	 */
7917c478bd9Sstevel@tonic-gate 	MD5Init(&ctx);
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src,
7947c478bd9Sstevel@tonic-gate 		  sizeof(fin->fin_fi.fi_src));
7957c478bd9Sstevel@tonic-gate 	MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst,
7967c478bd9Sstevel@tonic-gate 		  sizeof(fin->fin_fi.fi_dst));
7977c478bd9Sstevel@tonic-gate 	MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat));
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 	/* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	MD5Final(hash, &ctx);
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	memcpy(&newiss, hash, sizeof(newiss));
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	/*
8067c478bd9Sstevel@tonic-gate 	 * Now increment our "timer", and add it in to
8077c478bd9Sstevel@tonic-gate 	 * the computed value.
8087c478bd9Sstevel@tonic-gate 	 *
8097c478bd9Sstevel@tonic-gate 	 * XXX Use `addin'?
8107c478bd9Sstevel@tonic-gate 	 * XXX TCP_ISSINCR too large to use?
8117c478bd9Sstevel@tonic-gate 	 */
8127c478bd9Sstevel@tonic-gate 	iss_seq_off += 0x00010000;
8137c478bd9Sstevel@tonic-gate 	newiss += iss_seq_off;
8147c478bd9Sstevel@tonic-gate 	return newiss;
8157c478bd9Sstevel@tonic-gate }
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
8197c478bd9Sstevel@tonic-gate /* Function:    fr_nextipid                                                 */
8207c478bd9Sstevel@tonic-gate /* Returns:     int - 0 == success, -1 == error (packet should be droppped) */
8217c478bd9Sstevel@tonic-gate /* Parameters:  fin(I) - pointer to packet information                      */
8227c478bd9Sstevel@tonic-gate /*                                                                          */
8237c478bd9Sstevel@tonic-gate /* Returns the next IPv4 ID to use for this packet.                         */
8247c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
8257c478bd9Sstevel@tonic-gate INLINE u_short fr_nextipid(fin)
8267c478bd9Sstevel@tonic-gate fr_info_t *fin;
8277c478bd9Sstevel@tonic-gate {
8287c478bd9Sstevel@tonic-gate 	static u_short ipid = 0;
8297c478bd9Sstevel@tonic-gate 	u_short id;
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 	MUTEX_ENTER(&ipf_rw);
8327c478bd9Sstevel@tonic-gate 	id = ipid++;
8337c478bd9Sstevel@tonic-gate 	MUTEX_EXIT(&ipf_rw);
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 	return id;
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate INLINE void fr_checkv4sum(fin)
8407c478bd9Sstevel@tonic-gate fr_info_t *fin;
8417c478bd9Sstevel@tonic-gate {
8427c478bd9Sstevel@tonic-gate 	if (fr_checkl4sum(fin) == -1)
8437c478bd9Sstevel@tonic-gate 		fin->fin_flx |= FI_BAD;
8447c478bd9Sstevel@tonic-gate }
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate #ifdef	USE_INET6
8487c478bd9Sstevel@tonic-gate INLINE void fr_checkv6sum(fin)
8497c478bd9Sstevel@tonic-gate fr_info_t *fin;
8507c478bd9Sstevel@tonic-gate {
8517c478bd9Sstevel@tonic-gate 	if (fr_checkl4sum(fin) == -1)
8527c478bd9Sstevel@tonic-gate 		fin->fin_flx |= FI_BAD;
8537c478bd9Sstevel@tonic-gate }
8547c478bd9Sstevel@tonic-gate #endif
855