xref: /onnv-gate/usr/src/cmd/ipf/tools/ip_fil.c (revision 8624:0c81faef90eb)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright (C) 1993-2001, 2003 by Darren Reed.
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
50Sstevel@tonic-gate  *
6*8624SDarren.Reed@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
70Sstevel@tonic-gate  * Use is subject to license terms.
80Sstevel@tonic-gate  */
90Sstevel@tonic-gate 
100Sstevel@tonic-gate #if !defined(lint)
112393Syz155240 static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
122393Syz155240 static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.9 2005/01/08 14:22:18 darrenr Exp $";
130Sstevel@tonic-gate #endif
140Sstevel@tonic-gate 
150Sstevel@tonic-gate #ifndef	SOLARIS
160Sstevel@tonic-gate #define	SOLARIS	(defined(sun) && (defined(__svr4__) || defined(__SVR4)))
170Sstevel@tonic-gate #endif
180Sstevel@tonic-gate 
190Sstevel@tonic-gate #include <sys/param.h>
200Sstevel@tonic-gate #if defined(__FreeBSD__) && !defined(__FreeBSD_version)
210Sstevel@tonic-gate # if defined(IPFILTER_LKM)
220Sstevel@tonic-gate #  ifndef __FreeBSD_cc_version
230Sstevel@tonic-gate #   include <osreldate.h>
240Sstevel@tonic-gate #  else
250Sstevel@tonic-gate #   if __FreeBSD_cc_version < 430000
260Sstevel@tonic-gate #    include <osreldate.h>
270Sstevel@tonic-gate #   endif
280Sstevel@tonic-gate #  endif
290Sstevel@tonic-gate # endif
300Sstevel@tonic-gate #endif
310Sstevel@tonic-gate #include <sys/errno.h>
322393Syz155240 #if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL)
332393Syz155240 # include <sys/kern_svcs.h>
342393Syz155240 #endif
350Sstevel@tonic-gate #include <sys/types.h>
362393Syz155240 #define _KERNEL
372393Syz155240 #define KERNEL
382393Syz155240 #ifdef __OpenBSD__
390Sstevel@tonic-gate struct file;
400Sstevel@tonic-gate #endif
412393Syz155240 #include <sys/uio.h>
422393Syz155240 #undef _KERNEL
432393Syz155240 #undef KERNEL
440Sstevel@tonic-gate #include <sys/file.h>
450Sstevel@tonic-gate #include <sys/ioctl.h>
460Sstevel@tonic-gate #ifdef __sgi
470Sstevel@tonic-gate # include <sys/ptimers.h>
480Sstevel@tonic-gate #endif
490Sstevel@tonic-gate #include <sys/time.h>
500Sstevel@tonic-gate #if !SOLARIS
510Sstevel@tonic-gate # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
520Sstevel@tonic-gate #  include <sys/dirent.h>
530Sstevel@tonic-gate # else
540Sstevel@tonic-gate #  include <sys/dir.h>
550Sstevel@tonic-gate # endif
560Sstevel@tonic-gate #else
570Sstevel@tonic-gate # include <sys/filio.h>
580Sstevel@tonic-gate #endif
592393Syz155240 #ifndef linux
602393Syz155240 # include <sys/protosw.h>
612393Syz155240 #endif
620Sstevel@tonic-gate #include <sys/socket.h>
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #include <stdio.h>
650Sstevel@tonic-gate #include <string.h>
660Sstevel@tonic-gate #include <stdlib.h>
670Sstevel@tonic-gate #include <ctype.h>
680Sstevel@tonic-gate #include <fcntl.h>
693448Sdh155122 #include <sys/zone.h>
702393Syz155240 #include <arpa/inet.h>
710Sstevel@tonic-gate 
720Sstevel@tonic-gate #ifdef __hpux
730Sstevel@tonic-gate # define _NET_ROUTE_INCLUDED
740Sstevel@tonic-gate #endif
750Sstevel@tonic-gate #include <net/if.h>
760Sstevel@tonic-gate #ifdef sun
770Sstevel@tonic-gate # include <net/af.h>
780Sstevel@tonic-gate #endif
790Sstevel@tonic-gate #if __FreeBSD_version >= 300000
800Sstevel@tonic-gate # include <net/if_var.h>
810Sstevel@tonic-gate #endif
820Sstevel@tonic-gate #ifdef __sgi
830Sstevel@tonic-gate #include <sys/debug.h>
840Sstevel@tonic-gate # ifdef IFF_DRVRLOCK /* IRIX6 */
850Sstevel@tonic-gate #include <sys/hashing.h>
860Sstevel@tonic-gate # endif
870Sstevel@tonic-gate #endif
882393Syz155240 #if defined(__FreeBSD__)
892393Syz155240 # include "radix_ipf.h"
902393Syz155240 #endif
910Sstevel@tonic-gate #include <net/route.h>
920Sstevel@tonic-gate #include <netinet/in.h>
930Sstevel@tonic-gate #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \
942393Syz155240     !defined(__hpux) && !defined(linux)
950Sstevel@tonic-gate # include <netinet/in_var.h>
960Sstevel@tonic-gate #endif
970Sstevel@tonic-gate #include <netinet/in_systm.h>
980Sstevel@tonic-gate #include <netinet/ip.h>
992393Syz155240 #if !defined(linux)
1002393Syz155240 # include <netinet/ip_var.h>
1012393Syz155240 #endif
1020Sstevel@tonic-gate #include <netinet/tcp.h>
1030Sstevel@tonic-gate #if defined(__osf__)
1040Sstevel@tonic-gate # include <netinet/tcp_timer.h>
1050Sstevel@tonic-gate #endif
1062393Syz155240 #if defined(__osf__) || defined(__hpux) || defined(__sgi)
1072393Syz155240 # include "radix_ipf_local.h"
1082393Syz155240 # define _RADIX_H_
1092393Syz155240 #endif
1100Sstevel@tonic-gate #include <netinet/udp.h>
1110Sstevel@tonic-gate #include <netinet/tcpip.h>
1120Sstevel@tonic-gate #include <netinet/ip_icmp.h>
1130Sstevel@tonic-gate #include <unistd.h>
1140Sstevel@tonic-gate #include <syslog.h>
1150Sstevel@tonic-gate #ifdef __hpux
1160Sstevel@tonic-gate # undef _NET_ROUTE_INCLUDED
1170Sstevel@tonic-gate #endif
1180Sstevel@tonic-gate #include "netinet/ip_compat.h"
1190Sstevel@tonic-gate #include "netinet/ip_fil.h"
1200Sstevel@tonic-gate #include "netinet/ip_nat.h"
1210Sstevel@tonic-gate #include "netinet/ip_frag.h"
1220Sstevel@tonic-gate #include "netinet/ip_state.h"
1230Sstevel@tonic-gate #include "netinet/ip_proxy.h"
1240Sstevel@tonic-gate #include "netinet/ip_auth.h"
1250Sstevel@tonic-gate #ifdef	IPFILTER_SYNC
1260Sstevel@tonic-gate #include "netinet/ip_sync.h"
1270Sstevel@tonic-gate #endif
1280Sstevel@tonic-gate #ifdef	IPFILTER_SCAN
1290Sstevel@tonic-gate #include "netinet/ip_scan.h"
1300Sstevel@tonic-gate #endif
1310Sstevel@tonic-gate #include "netinet/ip_pool.h"
1320Sstevel@tonic-gate #ifdef IPFILTER_COMPILED
1330Sstevel@tonic-gate # include "netinet/ip_rules.h"
1340Sstevel@tonic-gate #endif
1353448Sdh155122 #include "netinet/ipf_stack.h"
1360Sstevel@tonic-gate #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
1370Sstevel@tonic-gate # include <sys/malloc.h>
1380Sstevel@tonic-gate #endif
1390Sstevel@tonic-gate #ifdef __hpux
1400Sstevel@tonic-gate struct rtentry;
1410Sstevel@tonic-gate #endif
1422393Syz155240 #include "md5.h"
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate #if !defined(__osf__)
1460Sstevel@tonic-gate extern	struct	protosw	inetsw[];
1470Sstevel@tonic-gate #endif
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate #include "ipt.h"
1500Sstevel@tonic-gate static	struct	ifnet **ifneta = NULL;
1510Sstevel@tonic-gate static	int	nifs = 0;
1520Sstevel@tonic-gate 
1533448Sdh155122 static	int	frzerostats __P((caddr_t, ipf_stack_t *ifs));
1542393Syz155240 static	void	fr_setifpaddr __P((struct ifnet *, char *));
1550Sstevel@tonic-gate void	init_ifp __P((void));
1562393Syz155240 #if defined(__sgi) && (IRIX < 60500)
1570Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1580Sstevel@tonic-gate 			       struct sockaddr *));
1590Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1600Sstevel@tonic-gate 				  struct sockaddr *));
1610Sstevel@tonic-gate #else
1620Sstevel@tonic-gate # if TRU64 >= 1885
1630Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1640Sstevel@tonic-gate 			       struct sockaddr *, struct rtentry *, char *));
1650Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1660Sstevel@tonic-gate 				  struct sockaddr *, struct rtentry *, char *));
1670Sstevel@tonic-gate # else
1680Sstevel@tonic-gate static int 	no_output __P((struct ifnet *, struct mbuf *,
1690Sstevel@tonic-gate 			       struct sockaddr *, struct rtentry *));
1700Sstevel@tonic-gate static int	write_output __P((struct ifnet *, struct mbuf *,
1710Sstevel@tonic-gate 				  struct sockaddr *, struct rtentry *));
1720Sstevel@tonic-gate # endif
1730Sstevel@tonic-gate #endif
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 
iplattach(ifs)1767513SDarren.Reed@Sun.COM int iplattach(ifs)
1773448Sdh155122 ipf_stack_t *ifs;
1780Sstevel@tonic-gate {
1793448Sdh155122 	ifs->ifs_fr_running = 1;
1800Sstevel@tonic-gate 	return 0;
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 
ipldetach(ifs)1843448Sdh155122 int ipldetach(ifs)
1853448Sdh155122 ipf_stack_t *ifs;
1860Sstevel@tonic-gate {
1873448Sdh155122 	ifs->ifs_fr_running = -1;
1880Sstevel@tonic-gate 	return 0;
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 
frzerostats(data,ifs)1923448Sdh155122 static	int	frzerostats(data, ifs)
1930Sstevel@tonic-gate caddr_t	data;
1943448Sdh155122 ipf_stack_t *ifs;
1950Sstevel@tonic-gate {
1960Sstevel@tonic-gate 	friostat_t fio;
1970Sstevel@tonic-gate 	int error;
1980Sstevel@tonic-gate 
1993448Sdh155122 	fr_getstat(&fio, ifs);
2000Sstevel@tonic-gate 	error = copyoutptr(&fio, data, sizeof(fio));
2010Sstevel@tonic-gate 	if (error)
2020Sstevel@tonic-gate 		return EFAULT;
2030Sstevel@tonic-gate 
2043448Sdh155122 	bzero((char *)ifs->ifs_frstats, sizeof(*ifs->ifs_frstats) * 2);
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	return 0;
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate /*
2110Sstevel@tonic-gate  * Filter ioctl interface.
2120Sstevel@tonic-gate  */
iplioctl(dev,cmd,data,mode)2130Sstevel@tonic-gate int iplioctl(dev, cmd, data, mode)
2140Sstevel@tonic-gate int dev;
2152393Syz155240 ioctlcmd_t cmd;
2160Sstevel@tonic-gate caddr_t data;
2170Sstevel@tonic-gate int mode;
2180Sstevel@tonic-gate {
2193448Sdh155122 	int error = 0, unit = 0, tmp, uid;
2200Sstevel@tonic-gate 	friostat_t fio;
2213448Sdh155122 	ipf_stack_t *ifs;
2223448Sdh155122 	extern ipf_stack_t *get_ifs();
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	unit = dev;
2253448Sdh155122 	uid = getuid();
2263448Sdh155122 
2273448Sdh155122 	ifs = get_ifs();
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	SPL_NET(s);
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	if (unit == IPL_LOGNAT) {
2323448Sdh155122 		if (ifs->ifs_fr_running > 0)
2333448Sdh155122 			error = fr_nat_ioctl(data, cmd, mode, uid, NULL, ifs);
2340Sstevel@tonic-gate 		else
2350Sstevel@tonic-gate 			error = EIO;
2360Sstevel@tonic-gate 		SPL_X(s);
2370Sstevel@tonic-gate 		return error;
2380Sstevel@tonic-gate 	}
2390Sstevel@tonic-gate 	if (unit == IPL_LOGSTATE) {
2403448Sdh155122 		if (ifs->ifs_fr_running > 0)
2413448Sdh155122 			error = fr_state_ioctl(data, cmd, mode, uid, NULL, ifs);
2420Sstevel@tonic-gate 		else
2430Sstevel@tonic-gate 			error = EIO;
2440Sstevel@tonic-gate 		SPL_X(s);
2450Sstevel@tonic-gate 		return error;
2460Sstevel@tonic-gate 	}
2470Sstevel@tonic-gate 	if (unit == IPL_LOGAUTH) {
2483448Sdh155122 		if (ifs->ifs_fr_running > 0) {
2492393Syz155240 			if ((cmd == (ioctlcmd_t)SIOCADAFR) ||
2502393Syz155240 			    (cmd == (ioctlcmd_t)SIOCRMAFR)) {
2510Sstevel@tonic-gate 				if (!(mode & FWRITE)) {
2520Sstevel@tonic-gate 					error = EPERM;
2530Sstevel@tonic-gate 				} else {
2540Sstevel@tonic-gate 					error = frrequest(unit, cmd, data,
2553448Sdh155122 					    ifs->ifs_fr_active, 1, ifs);
2560Sstevel@tonic-gate 				}
2570Sstevel@tonic-gate 			} else {
258*8624SDarren.Reed@Sun.COM 				error = fr_auth_ioctl(data, cmd, mode, uid,
259*8624SDarren.Reed@Sun.COM 						      NULL, ifs);
2600Sstevel@tonic-gate 			}
2610Sstevel@tonic-gate 		} else
2620Sstevel@tonic-gate 			error = EIO;
2630Sstevel@tonic-gate 		SPL_X(s);
2640Sstevel@tonic-gate 		return error;
2650Sstevel@tonic-gate 	}
2660Sstevel@tonic-gate 	if (unit == IPL_LOGSYNC) {
2670Sstevel@tonic-gate #ifdef	IPFILTER_SYNC
2683448Sdh155122 		if (ifs->ifs_fr_running > 0)
2690Sstevel@tonic-gate 			error = fr_sync_ioctl(data, cmd, mode);
2700Sstevel@tonic-gate 		else
2710Sstevel@tonic-gate #endif
2720Sstevel@tonic-gate 			error = EIO;
2730Sstevel@tonic-gate 		SPL_X(s);
2740Sstevel@tonic-gate 		return error;
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate 	if (unit == IPL_LOGSCAN) {
2770Sstevel@tonic-gate #ifdef	IPFILTER_SCAN
2783448Sdh155122 		if (ifs->ifs_fr_running > 0)
2790Sstevel@tonic-gate 			error = fr_scan_ioctl(data, cmd, mode);
2800Sstevel@tonic-gate 		else
2810Sstevel@tonic-gate #endif
2820Sstevel@tonic-gate 			error = EIO;
2830Sstevel@tonic-gate 		SPL_X(s);
2840Sstevel@tonic-gate 		return error;
2850Sstevel@tonic-gate 	}
2860Sstevel@tonic-gate 	if (unit == IPL_LOGLOOKUP) {
2873448Sdh155122 		if (ifs->ifs_fr_running > 0)
2883448Sdh155122 			error = ip_lookup_ioctl(data, cmd, mode, uid,
2893448Sdh155122 			    NULL, ifs);
2900Sstevel@tonic-gate 		else
2910Sstevel@tonic-gate 			error = EIO;
2920Sstevel@tonic-gate 		SPL_X(s);
2930Sstevel@tonic-gate 		return error;
2940Sstevel@tonic-gate 	}
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	switch (cmd)
2970Sstevel@tonic-gate 	{
2980Sstevel@tonic-gate 	case FIONREAD :
2990Sstevel@tonic-gate #ifdef IPFILTER_LOG
3003448Sdh155122 		error = COPYOUT(&ifs->ifs_iplused[IPL_LOGIPF], (caddr_t)data,
3013448Sdh155122 			       sizeof(ifs->ifs_iplused[IPL_LOGIPF]));
3020Sstevel@tonic-gate #endif
3030Sstevel@tonic-gate 		break;
3040Sstevel@tonic-gate 	case SIOCFRENB :
3050Sstevel@tonic-gate 		if (!(mode & FWRITE))
3060Sstevel@tonic-gate 			error = EPERM;
3070Sstevel@tonic-gate 		else {
3080Sstevel@tonic-gate 			error = COPYIN(data, &tmp, sizeof(tmp));
3090Sstevel@tonic-gate 			if (error)
3100Sstevel@tonic-gate 				break;
3110Sstevel@tonic-gate 			if (tmp)
3127513SDarren.Reed@Sun.COM 				error = iplattach(ifs);
3130Sstevel@tonic-gate 			else
3143448Sdh155122 				error = ipldetach(ifs);
3150Sstevel@tonic-gate 		}
3160Sstevel@tonic-gate 		break;
3172393Syz155240 	case SIOCIPFSET :
3182393Syz155240 		if (!(mode & FWRITE)) {
3192393Syz155240 			error = EPERM;
3202393Syz155240 			break;
3212393Syz155240 		}
3222393Syz155240 	case SIOCIPFGETNEXT :
3232393Syz155240 	case SIOCIPFGET :
3243448Sdh155122 		error = fr_ipftune(cmd, (void *)data, ifs);
3252393Syz155240 		break;
3260Sstevel@tonic-gate 	case SIOCSETFF :
3270Sstevel@tonic-gate 		if (!(mode & FWRITE))
3280Sstevel@tonic-gate 			error = EPERM;
3290Sstevel@tonic-gate 		else
3303448Sdh155122 			error = COPYIN(data, &ifs->ifs_fr_flags,
3313448Sdh155122 			    sizeof(ifs->ifs_fr_flags));
3320Sstevel@tonic-gate 		break;
3330Sstevel@tonic-gate 	case SIOCGETFF :
3343448Sdh155122 		error = COPYOUT(&ifs->ifs_fr_flags, data,
3353448Sdh155122 		    sizeof(ifs->ifs_fr_flags));
3360Sstevel@tonic-gate 		break;
3370Sstevel@tonic-gate 	case SIOCFUNCL :
3380Sstevel@tonic-gate 		error = fr_resolvefunc(data);
3390Sstevel@tonic-gate 		break;
3400Sstevel@tonic-gate 	case SIOCINAFR :
3410Sstevel@tonic-gate 	case SIOCRMAFR :
3420Sstevel@tonic-gate 	case SIOCADAFR :
3430Sstevel@tonic-gate 	case SIOCZRLST :
3440Sstevel@tonic-gate 		if (!(mode & FWRITE))
3450Sstevel@tonic-gate 			error = EPERM;
3460Sstevel@tonic-gate 		else
3473448Sdh155122 			error = frrequest(unit, cmd, data,
3483448Sdh155122 			    ifs->ifs_fr_active, 1, ifs);
3490Sstevel@tonic-gate 		break;
3500Sstevel@tonic-gate 	case SIOCINIFR :
3510Sstevel@tonic-gate 	case SIOCRMIFR :
3520Sstevel@tonic-gate 	case SIOCADIFR :
3530Sstevel@tonic-gate 		if (!(mode & FWRITE))
3540Sstevel@tonic-gate 			error = EPERM;
3550Sstevel@tonic-gate 		else
3563448Sdh155122 			error = frrequest(unit, cmd, data,
3573448Sdh155122 			    1 - ifs->ifs_fr_active, 1, ifs);
3580Sstevel@tonic-gate 		break;
3590Sstevel@tonic-gate 	case SIOCSWAPA :
3600Sstevel@tonic-gate 		if (!(mode & FWRITE))
3610Sstevel@tonic-gate 			error = EPERM;
3620Sstevel@tonic-gate 		else {
3633448Sdh155122 			*(u_int *)data = ifs->ifs_fr_active;
3643448Sdh155122 			ifs->ifs_fr_active = 1 - ifs->ifs_fr_active;
3650Sstevel@tonic-gate 		}
3660Sstevel@tonic-gate 		break;
3670Sstevel@tonic-gate 	case SIOCGETFS :
3683448Sdh155122 		fr_getstat(&fio, ifs);
3690Sstevel@tonic-gate 		error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT);
3700Sstevel@tonic-gate 		break;
3710Sstevel@tonic-gate 	case	SIOCFRZST :
3720Sstevel@tonic-gate 		if (!(mode & FWRITE))
3730Sstevel@tonic-gate 			error = EPERM;
3740Sstevel@tonic-gate 		else
3753448Sdh155122 			error = frzerostats(data, ifs);
3760Sstevel@tonic-gate 		break;
3770Sstevel@tonic-gate 	case	SIOCIPFFL :
3780Sstevel@tonic-gate 		if (!(mode & FWRITE))
3790Sstevel@tonic-gate 			error = EPERM;
3800Sstevel@tonic-gate 		else {
3810Sstevel@tonic-gate 			error = COPYIN(data, &tmp, sizeof(tmp));
3820Sstevel@tonic-gate 			if (!error) {
3833448Sdh155122 				tmp = frflush(unit, 4, tmp, ifs);
3840Sstevel@tonic-gate 				error = COPYOUT(&tmp, data, sizeof(tmp));
3850Sstevel@tonic-gate 			}
3860Sstevel@tonic-gate 		}
3870Sstevel@tonic-gate 		break;
388637Sml37995 #ifdef	USE_INET6
389637Sml37995 	case	SIOCIPFL6 :
390637Sml37995 		if (!(mode & FWRITE))
391637Sml37995 			error = EPERM;
392637Sml37995 		else {
393637Sml37995 			error = COPYIN(data, &tmp, sizeof(tmp));
394637Sml37995 			if (!error) {
3953448Sdh155122 				tmp = frflush(unit, 6, tmp, ifs);
396637Sml37995 				error = COPYOUT(&tmp, data, sizeof(tmp));
397637Sml37995 			}
398637Sml37995 		}
399637Sml37995 		break;
400637Sml37995 #endif
4010Sstevel@tonic-gate 	case SIOCSTLCK :
4020Sstevel@tonic-gate 		error = COPYIN(data, &tmp, sizeof(tmp));
4030Sstevel@tonic-gate 		if (error == 0) {
4043448Sdh155122 			ifs->ifs_fr_state_lock = tmp;
4053448Sdh155122 			ifs->ifs_fr_nat_lock = tmp;
4063448Sdh155122 			ifs->ifs_fr_frag_lock = tmp;
4073448Sdh155122 			ifs->ifs_fr_auth_lock = tmp;
4080Sstevel@tonic-gate 		} else
4090Sstevel@tonic-gate 			error = EFAULT;
4100Sstevel@tonic-gate 		break;
4110Sstevel@tonic-gate #ifdef	IPFILTER_LOG
4120Sstevel@tonic-gate 	case	SIOCIPFFB :
4130Sstevel@tonic-gate 		if (!(mode & FWRITE))
4140Sstevel@tonic-gate 			error = EPERM;
4150Sstevel@tonic-gate 		else
4163448Sdh155122 			*(int *)data = ipflog_clear(unit, ifs);
4170Sstevel@tonic-gate 		break;
4180Sstevel@tonic-gate #endif /* IPFILTER_LOG */
4190Sstevel@tonic-gate 	case SIOCGFRST :
4203448Sdh155122 		error = fr_outobj(data, fr_fragstats(ifs), IPFOBJ_FRAGSTAT);
4210Sstevel@tonic-gate 		break;
4220Sstevel@tonic-gate 	case SIOCFRSYN :
4230Sstevel@tonic-gate 		if (!(mode & FWRITE))
4240Sstevel@tonic-gate 			error = EPERM;
4250Sstevel@tonic-gate 		else {
4263448Sdh155122 			frsync(IPFSYNC_RESYNC, IPFSYNC_RESYNC, NULL, NULL, ifs);
4270Sstevel@tonic-gate 		}
4280Sstevel@tonic-gate 		break;
4290Sstevel@tonic-gate 	default :
4300Sstevel@tonic-gate 		error = EINVAL;
4310Sstevel@tonic-gate 		break;
4320Sstevel@tonic-gate 	}
4330Sstevel@tonic-gate 	SPL_X(s);
4340Sstevel@tonic-gate 	return error;
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 
fr_forgetifp(ifp,ifs)4383448Sdh155122 void fr_forgetifp(ifp, ifs)
4390Sstevel@tonic-gate void *ifp;
4403448Sdh155122 ipf_stack_t *ifs;
4410Sstevel@tonic-gate {
4420Sstevel@tonic-gate 	register frentry_t *f;
4430Sstevel@tonic-gate 
4443448Sdh155122 	WRITE_ENTER(&ifs->ifs_ipf_mutex);
4453448Sdh155122 	for (f = ifs->ifs_ipacct[0][ifs->ifs_fr_active]; (f != NULL);
4463448Sdh155122 	    f = f->fr_next)
4470Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4480Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4493448Sdh155122 	for (f = ifs->ifs_ipacct[1][ifs->ifs_fr_active]; (f != NULL);
4503448Sdh155122 	    f = f->fr_next)
4510Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4520Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4533448Sdh155122 	for (f = ifs->ifs_ipfilter[0][ifs->ifs_fr_active]; (f != NULL);
4543448Sdh155122 	    f = f->fr_next)
4550Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4560Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4573448Sdh155122 	for (f = ifs->ifs_ipfilter[1][ifs->ifs_fr_active]; (f != NULL);
4583448Sdh155122 	    f = f->fr_next)
4590Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4600Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4610Sstevel@tonic-gate #ifdef	USE_INET6
4623448Sdh155122 	for (f = ifs->ifs_ipacct6[0][ifs->ifs_fr_active]; (f != NULL);
4633448Sdh155122 	    f = f->fr_next)
4640Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4650Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4663448Sdh155122 	for (f = ifs->ifs_ipacct6[1][ifs->ifs_fr_active]; (f != NULL);
4673448Sdh155122 	    f = f->fr_next)
4680Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4690Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4703448Sdh155122 	for (f = ifs->ifs_ipfilter6[0][ifs->ifs_fr_active]; (f != NULL);
4713448Sdh155122 	    f = f->fr_next)
4720Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4730Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4743448Sdh155122 	for (f = ifs->ifs_ipfilter6[1][ifs->ifs_fr_active]; (f != NULL);
4753448Sdh155122 	    f = f->fr_next)
4760Sstevel@tonic-gate 		if (f->fr_ifa == ifp)
4770Sstevel@tonic-gate 			f->fr_ifa = (void *)-1;
4780Sstevel@tonic-gate #endif
4793448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ipf_mutex);
4807176Syx160601 	fr_natifpsync(IPFSYNC_OLDIFP, 4, ifp, NULL, ifs);
4817176Syx160601 	fr_natifpsync(IPFSYNC_OLDIFP, 6, ifp, NULL, ifs);
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate 
fr_resolvedest(fdp,v,ifs)4853448Sdh155122 void fr_resolvedest(fdp, v, ifs)
4860Sstevel@tonic-gate frdest_t *fdp;
4870Sstevel@tonic-gate int v;
4883448Sdh155122 ipf_stack_t *ifs;
4890Sstevel@tonic-gate {
4900Sstevel@tonic-gate 	fdp->fd_ifp = NULL;
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 	if (*fdp->fd_ifname) {
4933448Sdh155122 		fdp->fd_ifp = GETIFP(fdp->fd_ifname, v, ifs);
4940Sstevel@tonic-gate 		if (!fdp->fd_ifp)
4950Sstevel@tonic-gate 			fdp->fd_ifp = (struct ifnet *)-1;
4960Sstevel@tonic-gate 	}
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate 
5002393Syz155240 #if defined(__sgi) && (IRIX < 60500)
no_output(ifp,m,s)5010Sstevel@tonic-gate static int no_output(ifp, m, s)
5020Sstevel@tonic-gate #else
5030Sstevel@tonic-gate # if TRU64 >= 1885
5040Sstevel@tonic-gate static int no_output (ifp, m, s, rt, cp)
5050Sstevel@tonic-gate char *cp;
5060Sstevel@tonic-gate # else
5070Sstevel@tonic-gate static int no_output(ifp, m, s, rt)
5080Sstevel@tonic-gate # endif
5090Sstevel@tonic-gate struct rtentry *rt;
5100Sstevel@tonic-gate #endif
5110Sstevel@tonic-gate struct ifnet *ifp;
5120Sstevel@tonic-gate struct mbuf *m;
5130Sstevel@tonic-gate struct sockaddr *s;
5140Sstevel@tonic-gate {
5150Sstevel@tonic-gate 	return 0;
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 
5192393Syz155240 #if defined(__sgi) && (IRIX < 60500)
write_output(ifp,m,s)5200Sstevel@tonic-gate static int write_output(ifp, m, s)
5210Sstevel@tonic-gate #else
5220Sstevel@tonic-gate # if TRU64 >= 1885
5230Sstevel@tonic-gate static int write_output (ifp, m, s, rt, cp)
5240Sstevel@tonic-gate char *cp;
5250Sstevel@tonic-gate # else
5260Sstevel@tonic-gate static int write_output(ifp, m, s, rt)
5270Sstevel@tonic-gate # endif
5280Sstevel@tonic-gate struct rtentry *rt;
5290Sstevel@tonic-gate #endif
5300Sstevel@tonic-gate struct ifnet *ifp;
5310Sstevel@tonic-gate struct mbuf *m;
5320Sstevel@tonic-gate struct sockaddr *s;
5330Sstevel@tonic-gate {
5340Sstevel@tonic-gate 	char fname[32];
5350Sstevel@tonic-gate 	mb_t *mb;
5360Sstevel@tonic-gate 	ip_t *ip;
5370Sstevel@tonic-gate 	int fd;
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 	mb = (mb_t *)m;
5400Sstevel@tonic-gate 	ip = MTOD(mb, ip_t *);
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
5432393Syz155240     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
5442393Syz155240     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
5450Sstevel@tonic-gate 	sprintf(fname, "/tmp/%s", ifp->if_xname);
5460Sstevel@tonic-gate #else
5470Sstevel@tonic-gate 	sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
5480Sstevel@tonic-gate #endif
5490Sstevel@tonic-gate 	fd = open(fname, O_WRONLY|O_APPEND);
5500Sstevel@tonic-gate 	if (fd == -1) {
5510Sstevel@tonic-gate 		perror("open");
5520Sstevel@tonic-gate 		return -1;
5530Sstevel@tonic-gate 	}
5540Sstevel@tonic-gate 	write(fd, (char *)ip, ntohs(ip->ip_len));
5550Sstevel@tonic-gate 	close(fd);
5560Sstevel@tonic-gate 	return 0;
5570Sstevel@tonic-gate }
5580Sstevel@tonic-gate 
5590Sstevel@tonic-gate 
fr_setifpaddr(ifp,addr)5602393Syz155240 static void fr_setifpaddr(ifp, addr)
5612393Syz155240 struct ifnet *ifp;
5622393Syz155240 char *addr;
5632393Syz155240 {
5642393Syz155240 #ifdef __sgi
5652393Syz155240 	struct in_ifaddr *ifa;
5662393Syz155240 #else
5672393Syz155240 	struct ifaddr *ifa;
5682393Syz155240 #endif
5692393Syz155240 
5702393Syz155240 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
5712393Syz155240 	if (ifp->if_addrlist.tqh_first != NULL)
5722393Syz155240 #else
5732393Syz155240 # ifdef __sgi
5742393Syz155240 	if (ifp->in_ifaddr != NULL)
5752393Syz155240 # else
5762393Syz155240 	if (ifp->if_addrlist != NULL)
5772393Syz155240 # endif
5782393Syz155240 #endif
5792393Syz155240 		return;
5802393Syz155240 
5812393Syz155240 	ifa = (struct ifaddr *)malloc(sizeof(*ifa));
5822393Syz155240 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
5832393Syz155240 	ifp->if_addrlist.tqh_first = ifa;
5842393Syz155240 #else
5852393Syz155240 # ifdef __sgi
5862393Syz155240 	ifp->in_ifaddr = ifa;
5872393Syz155240 # else
5882393Syz155240 	ifp->if_addrlist = ifa;
5892393Syz155240 # endif
5902393Syz155240 #endif
5912393Syz155240 
5922393Syz155240 	if (ifa != NULL) {
5932393Syz155240 		struct sockaddr_in *sin;
5942393Syz155240 
5952393Syz155240 #ifdef __sgi
5962393Syz155240 		sin = (struct sockaddr_in *)&ifa->ia_addr;
5972393Syz155240 #else
5982393Syz155240 		sin = (struct sockaddr_in *)&ifa->ifa_addr;
5992393Syz155240 #endif
6002393Syz155240 		sin->sin_addr.s_addr = inet_addr(addr);
6012393Syz155240 		if (sin->sin_addr.s_addr == 0)
6022393Syz155240 			abort();
6032393Syz155240 	}
6042393Syz155240 }
6052393Syz155240 
6063448Sdh155122 /*ARGSUSED*/
get_unit(name,v,ifs)6073448Sdh155122 struct ifnet *get_unit(name, v, ifs)
6080Sstevel@tonic-gate char *name;
6090Sstevel@tonic-gate int v;
6103448Sdh155122 ipf_stack_t *ifs;
6110Sstevel@tonic-gate {
6122393Syz155240 	struct ifnet *ifp, **ifpp, **old_ifneta;
6132393Syz155240 	char *addr;
6140Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
6152393Syz155240     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
6162393Syz155240     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate 	if (name == NULL)
6190Sstevel@tonic-gate 		name = "anon0";
6200Sstevel@tonic-gate 
6212393Syz155240 	addr = strchr(name, '=');
6222393Syz155240 	if (addr != NULL)
6232393Syz155240 		*addr++ = '\0';
6242393Syz155240 
6252393Syz155240 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
6262393Syz155240 		if (!strcmp(name, ifp->if_xname)) {
6272393Syz155240 			if (addr != NULL)
6282393Syz155240 				fr_setifpaddr(ifp, addr);
6290Sstevel@tonic-gate 			return ifp;
6302393Syz155240 		}
6310Sstevel@tonic-gate 	}
6320Sstevel@tonic-gate #else
6330Sstevel@tonic-gate 	char *s, ifname[LIFNAMSIZ+1];
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	if (name == NULL)
6360Sstevel@tonic-gate 		name = "anon0";
6370Sstevel@tonic-gate 
6382393Syz155240 	addr = strchr(name, '=');
6392393Syz155240 	if (addr != NULL)
6402393Syz155240 		*addr++ = '\0';
6412393Syz155240 
6422393Syz155240 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
6432958Sdr146992 		COPYIFNAME(ifp, ifname, 0);
6442393Syz155240 		if (!strcmp(name, ifname)) {
6452393Syz155240 			if (addr != NULL)
6462393Syz155240 				fr_setifpaddr(ifp, addr);
6470Sstevel@tonic-gate 			return ifp;
6482393Syz155240 		}
6490Sstevel@tonic-gate 	}
6500Sstevel@tonic-gate #endif
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate 	if (!ifneta) {
6530Sstevel@tonic-gate 		ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
6540Sstevel@tonic-gate 		if (!ifneta)
6550Sstevel@tonic-gate 			return NULL;
6560Sstevel@tonic-gate 		ifneta[1] = NULL;
6570Sstevel@tonic-gate 		ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
6580Sstevel@tonic-gate 		if (!ifneta[0]) {
6590Sstevel@tonic-gate 			free(ifneta);
6600Sstevel@tonic-gate 			return NULL;
6610Sstevel@tonic-gate 		}
6620Sstevel@tonic-gate 		nifs = 1;
6630Sstevel@tonic-gate 	} else {
6640Sstevel@tonic-gate 		old_ifneta = ifneta;
6650Sstevel@tonic-gate 		nifs++;
6660Sstevel@tonic-gate 		ifneta = (struct ifnet **)realloc(ifneta,
6672393Syz155240 						  (nifs + 1) * sizeof(ifp));
6680Sstevel@tonic-gate 		if (!ifneta) {
6690Sstevel@tonic-gate 			free(old_ifneta);
6700Sstevel@tonic-gate 			nifs = 0;
6710Sstevel@tonic-gate 			return NULL;
6720Sstevel@tonic-gate 		}
6730Sstevel@tonic-gate 		ifneta[nifs] = NULL;
6740Sstevel@tonic-gate 		ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
6750Sstevel@tonic-gate 		if (!ifneta[nifs - 1]) {
6760Sstevel@tonic-gate 			nifs--;
6770Sstevel@tonic-gate 			return NULL;
6780Sstevel@tonic-gate 		}
6790Sstevel@tonic-gate 	}
6800Sstevel@tonic-gate 	ifp = ifneta[nifs - 1];
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
6832393Syz155240     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
6842393Syz155240     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
6852393Syz155240 	(void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
6860Sstevel@tonic-gate #else
6872393Syz155240 	for (s = name; *s && !ISDIGIT(*s); s++)
6880Sstevel@tonic-gate 		;
6892393Syz155240 	if (*s && ISDIGIT(*s)) {
6900Sstevel@tonic-gate 		ifp->if_unit = atoi(s);
6910Sstevel@tonic-gate 		ifp->if_name = (char *)malloc(s - name + 1);
6921448Sschuster 		if (ifp->if_name == NULL) {
6931448Sschuster 			/*
6941448Sschuster 			 * XXX do it more elegantly: free up mem,
6951448Sschuster 			 * return NULL
6961448Sschuster 			 */
6971448Sschuster 			perror("malloc");
6981448Sschuster 			exit(1);
6991448Sschuster 		}
7002393Syz155240 		(void) strncpy(ifp->if_name, name, s - name);
7010Sstevel@tonic-gate 		ifp->if_name[s - name] = '\0';
7020Sstevel@tonic-gate 	} else {
7030Sstevel@tonic-gate 		ifp->if_name = strdup(name);
7040Sstevel@tonic-gate 		ifp->if_unit = -1;
7050Sstevel@tonic-gate 	}
7060Sstevel@tonic-gate #endif
7070Sstevel@tonic-gate 	ifp->if_output = no_output;
7082393Syz155240 
7092393Syz155240 	if (addr != NULL) {
7102393Syz155240 		fr_setifpaddr(ifp, addr);
7112393Syz155240 	}
7122393Syz155240 
7130Sstevel@tonic-gate 	return ifp;
7140Sstevel@tonic-gate }
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 
get_ifname(ifp)7170Sstevel@tonic-gate char *get_ifname(ifp)
7180Sstevel@tonic-gate struct ifnet *ifp;
7190Sstevel@tonic-gate {
7200Sstevel@tonic-gate 	static char ifname[LIFNAMSIZ];
7210Sstevel@tonic-gate 
7222393Syz155240 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \
7232393Syz155240     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
7240Sstevel@tonic-gate 	sprintf(ifname, "%s", ifp->if_xname);
7250Sstevel@tonic-gate #else
7260Sstevel@tonic-gate 	sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
7270Sstevel@tonic-gate #endif
7280Sstevel@tonic-gate 	return ifname;
7290Sstevel@tonic-gate }
7300Sstevel@tonic-gate 
7310Sstevel@tonic-gate 
7320Sstevel@tonic-gate 
init_ifp()7330Sstevel@tonic-gate void init_ifp()
7340Sstevel@tonic-gate {
7352393Syz155240 	struct ifnet *ifp, **ifpp;
7360Sstevel@tonic-gate 	char fname[32];
7370Sstevel@tonic-gate 	int fd;
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
7402393Syz155240     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
7412393Syz155240     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
7422393Syz155240 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
7430Sstevel@tonic-gate 		ifp->if_output = write_output;
7440Sstevel@tonic-gate 		sprintf(fname, "/tmp/%s", ifp->if_xname);
7450Sstevel@tonic-gate 		fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
7460Sstevel@tonic-gate 		if (fd == -1)
7470Sstevel@tonic-gate 			perror("open");
7480Sstevel@tonic-gate 		else
7490Sstevel@tonic-gate 			close(fd);
7500Sstevel@tonic-gate 	}
7510Sstevel@tonic-gate #else
7520Sstevel@tonic-gate 
7532393Syz155240 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
7540Sstevel@tonic-gate 		ifp->if_output = write_output;
7550Sstevel@tonic-gate 		sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
7560Sstevel@tonic-gate 		fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
7570Sstevel@tonic-gate 		if (fd == -1)
7580Sstevel@tonic-gate 			perror("open");
7590Sstevel@tonic-gate 		else
7600Sstevel@tonic-gate 			close(fd);
7610Sstevel@tonic-gate 	}
7620Sstevel@tonic-gate #endif
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate 
7650Sstevel@tonic-gate 
fr_fastroute(m,mpp,fin,fdp)7660Sstevel@tonic-gate int fr_fastroute(m, mpp, fin, fdp)
7670Sstevel@tonic-gate mb_t *m, **mpp;
7680Sstevel@tonic-gate fr_info_t *fin;
7690Sstevel@tonic-gate frdest_t *fdp;
7700Sstevel@tonic-gate {
7710Sstevel@tonic-gate 	struct ifnet *ifp = fdp->fd_ifp;
7720Sstevel@tonic-gate 	ip_t *ip = fin->fin_ip;
7730Sstevel@tonic-gate 
7740Sstevel@tonic-gate 	if (!ifp)
7750Sstevel@tonic-gate 		return 0;	/* no routing table out here */
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	ip->ip_len = htons((u_short)ip->ip_len);
7780Sstevel@tonic-gate 	ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
7790Sstevel@tonic-gate 	ip->ip_sum = 0;
7802393Syz155240 #if defined(__sgi) && (IRIX < 60500)
7810Sstevel@tonic-gate 	(*ifp->if_output)(ifp, (void *)ip, NULL);
7820Sstevel@tonic-gate # if TRU64 >= 1885
7830Sstevel@tonic-gate 	(*ifp->if_output)(ifp, (void *)m, NULL, 0, 0);
7840Sstevel@tonic-gate # else
7850Sstevel@tonic-gate 	(*ifp->if_output)(ifp, (void *)m, NULL, 0);
7860Sstevel@tonic-gate # endif
7870Sstevel@tonic-gate #endif
7880Sstevel@tonic-gate 	return 0;
7890Sstevel@tonic-gate }
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate 
fr_send_reset(fin)7920Sstevel@tonic-gate int fr_send_reset(fin)
7930Sstevel@tonic-gate fr_info_t *fin;
7940Sstevel@tonic-gate {
7950Sstevel@tonic-gate 	verbose("- TCP RST sent\n");
7960Sstevel@tonic-gate 	return 0;
7970Sstevel@tonic-gate }
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 
fr_send_icmp_err(type,fin,dst)8000Sstevel@tonic-gate int fr_send_icmp_err(type, fin, dst)
8010Sstevel@tonic-gate int type;
8020Sstevel@tonic-gate fr_info_t *fin;
8030Sstevel@tonic-gate int dst;
8040Sstevel@tonic-gate {
8052393Syz155240 	verbose("- ICMP unreachable sent\n");
8060Sstevel@tonic-gate 	return 0;
8070Sstevel@tonic-gate }
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 
frsync(command,version,nic,data,ifs)8103448Sdh155122 void frsync(command, version, nic, data, ifs)
8112958Sdr146992 int command, version;
8122958Sdr146992 void *nic;
8132958Sdr146992 char *data;
8143448Sdh155122 ipf_stack_t *ifs;
8150Sstevel@tonic-gate {
8160Sstevel@tonic-gate 	return;
8170Sstevel@tonic-gate }
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 
m_freem(m)8200Sstevel@tonic-gate void m_freem(m)
8210Sstevel@tonic-gate mb_t *m;
8220Sstevel@tonic-gate {
8230Sstevel@tonic-gate 	return;
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate 
m_copydata(m,off,len,cp)8270Sstevel@tonic-gate void m_copydata(m, off, len, cp)
8280Sstevel@tonic-gate mb_t *m;
8290Sstevel@tonic-gate int off, len;
8300Sstevel@tonic-gate caddr_t cp;
8310Sstevel@tonic-gate {
8320Sstevel@tonic-gate 	bcopy((char *)m + off, cp, len);
8330Sstevel@tonic-gate }
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate 
ipfuiomove(buf,len,rwflag,uio)8360Sstevel@tonic-gate int ipfuiomove(buf, len, rwflag, uio)
8370Sstevel@tonic-gate caddr_t buf;
8380Sstevel@tonic-gate int len, rwflag;
8390Sstevel@tonic-gate struct uio *uio;
8400Sstevel@tonic-gate {
8410Sstevel@tonic-gate 	int left, ioc, num, offset;
8420Sstevel@tonic-gate 	struct iovec *io;
8430Sstevel@tonic-gate 	char *start;
8440Sstevel@tonic-gate 
8450Sstevel@tonic-gate 	if (rwflag == UIO_READ) {
8460Sstevel@tonic-gate 		left = len;
8470Sstevel@tonic-gate 		ioc = 0;
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 		offset = uio->uio_offset;
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate 		while ((left > 0) && (ioc < uio->uio_iovcnt)) {
8520Sstevel@tonic-gate 			io = uio->uio_iov + ioc;
8530Sstevel@tonic-gate 			num = io->iov_len;
8540Sstevel@tonic-gate 			if (num > left)
8550Sstevel@tonic-gate 				num = left;
8560Sstevel@tonic-gate 			start = (char *)io->iov_base + offset;
8570Sstevel@tonic-gate 			if (start > (char *)io->iov_base + io->iov_len) {
8580Sstevel@tonic-gate 				offset -= io->iov_len;
8590Sstevel@tonic-gate 				ioc++;
8600Sstevel@tonic-gate 				continue;
8610Sstevel@tonic-gate 			}
8620Sstevel@tonic-gate 			bcopy(buf, start, num);
8630Sstevel@tonic-gate 			uio->uio_resid -= num;
8640Sstevel@tonic-gate 			uio->uio_offset += num;
8650Sstevel@tonic-gate 			left -= num;
8660Sstevel@tonic-gate 			if (left > 0)
8670Sstevel@tonic-gate 				ioc++;
8680Sstevel@tonic-gate 		}
8690Sstevel@tonic-gate 		if (left > 0)
8700Sstevel@tonic-gate 			return EFAULT;
8710Sstevel@tonic-gate 	}
8720Sstevel@tonic-gate 	return 0;
8730Sstevel@tonic-gate }
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate 
fr_newisn(fin)8760Sstevel@tonic-gate u_32_t fr_newisn(fin)
8770Sstevel@tonic-gate fr_info_t *fin;
8780Sstevel@tonic-gate {
8790Sstevel@tonic-gate 	static int iss_seq_off = 0;
8800Sstevel@tonic-gate 	u_char hash[16];
8810Sstevel@tonic-gate 	u_32_t newiss;
8820Sstevel@tonic-gate 	MD5_CTX ctx;
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	/*
8850Sstevel@tonic-gate 	 * Compute the base value of the ISS.  It is a hash
8860Sstevel@tonic-gate 	 * of (saddr, sport, daddr, dport, secret).
8870Sstevel@tonic-gate 	 */
8880Sstevel@tonic-gate 	MD5Init(&ctx);
8890Sstevel@tonic-gate 
8900Sstevel@tonic-gate 	MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src,
8910Sstevel@tonic-gate 		  sizeof(fin->fin_fi.fi_src));
8920Sstevel@tonic-gate 	MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst,
8930Sstevel@tonic-gate 		  sizeof(fin->fin_fi.fi_dst));
8940Sstevel@tonic-gate 	MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat));
8950Sstevel@tonic-gate 
8960Sstevel@tonic-gate 	/* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate 	MD5Final(hash, &ctx);
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 	memcpy(&newiss, hash, sizeof(newiss));
9010Sstevel@tonic-gate 
9020Sstevel@tonic-gate 	/*
9030Sstevel@tonic-gate 	 * Now increment our "timer", and add it in to
9040Sstevel@tonic-gate 	 * the computed value.
9050Sstevel@tonic-gate 	 *
9060Sstevel@tonic-gate 	 * XXX Use `addin'?
9070Sstevel@tonic-gate 	 * XXX TCP_ISSINCR too large to use?
9080Sstevel@tonic-gate 	 */
9090Sstevel@tonic-gate 	iss_seq_off += 0x00010000;
9100Sstevel@tonic-gate 	newiss += iss_seq_off;
9110Sstevel@tonic-gate 	return newiss;
9120Sstevel@tonic-gate }
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 
9150Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
9160Sstevel@tonic-gate /* Function:    fr_nextipid                                                 */
9170Sstevel@tonic-gate /* Returns:     int - 0 == success, -1 == error (packet should be droppped) */
9180Sstevel@tonic-gate /* Parameters:  fin(I) - pointer to packet information                      */
9190Sstevel@tonic-gate /*                                                                          */
9200Sstevel@tonic-gate /* Returns the next IPv4 ID to use for this packet.                         */
9210Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
fr_nextipid(fin)9220Sstevel@tonic-gate INLINE u_short fr_nextipid(fin)
9230Sstevel@tonic-gate fr_info_t *fin;
9240Sstevel@tonic-gate {
9250Sstevel@tonic-gate 	static u_short ipid = 0;
9260Sstevel@tonic-gate 	u_short id;
9273448Sdh155122 	ipf_stack_t *ifs = fin->fin_ifs;
9280Sstevel@tonic-gate 
9293448Sdh155122 	MUTEX_ENTER(&ifs->ifs_ipf_rw);
9300Sstevel@tonic-gate 	id = ipid++;
9313448Sdh155122 	MUTEX_EXIT(&ifs->ifs_ipf_rw);
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	return id;
9340Sstevel@tonic-gate }
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 
fr_checkv4sum(fin)9370Sstevel@tonic-gate INLINE void fr_checkv4sum(fin)
9380Sstevel@tonic-gate fr_info_t *fin;
9390Sstevel@tonic-gate {
9400Sstevel@tonic-gate 	if (fr_checkl4sum(fin) == -1)
9410Sstevel@tonic-gate 		fin->fin_flx |= FI_BAD;
9420Sstevel@tonic-gate }
9430Sstevel@tonic-gate 
9440Sstevel@tonic-gate 
9450Sstevel@tonic-gate #ifdef	USE_INET6
fr_checkv6sum(fin)9460Sstevel@tonic-gate INLINE void fr_checkv6sum(fin)
9470Sstevel@tonic-gate fr_info_t *fin;
9480Sstevel@tonic-gate {
9490Sstevel@tonic-gate 	if (fr_checkl4sum(fin) == -1)
9500Sstevel@tonic-gate 		fin->fin_flx |= FI_BAD;
9510Sstevel@tonic-gate }
9520Sstevel@tonic-gate #endif
9532393Syz155240 
9542393Syz155240 
9552393Syz155240 /*
9562393Syz155240  * See above for description, except that all addressing is in user space.
9572393Syz155240  */
copyoutptr(src,dst,size)9582393Syz155240 int copyoutptr(src, dst, size)
9592393Syz155240 void *src, *dst;
9602393Syz155240 size_t size;
9612393Syz155240 {
9622393Syz155240 	caddr_t ca;
9632393Syz155240 
9642393Syz155240 	bcopy(dst, (char *)&ca, sizeof(ca));
9652393Syz155240 	bcopy(src, ca, size);
9662393Syz155240 	return 0;
9672393Syz155240 }
9682393Syz155240 
9692393Syz155240 
9702393Syz155240 /*
9712393Syz155240  * See above for description, except that all addressing is in user space.
9722393Syz155240  */
copyinptr(src,dst,size)9732393Syz155240 int copyinptr(src, dst, size)
9742393Syz155240 void *src, *dst;
9752393Syz155240 size_t size;
9762393Syz155240 {
9772393Syz155240 	caddr_t ca;
9782393Syz155240 
9792393Syz155240 	bcopy(src, (char *)&ca, sizeof(ca));
9802393Syz155240 	bcopy(ca, dst, size);
9812393Syz155240 	return 0;
9822393Syz155240 }
9832393Syz155240 
9842393Syz155240 
9852393Syz155240 /*
9862393Syz155240  * return the first IP Address associated with an interface
9872393Syz155240  */
fr_ifpaddr(v,atype,ifptr,inp,inpmask,ifs)9883448Sdh155122 int fr_ifpaddr(v, atype, ifptr, inp, inpmask, ifs)
9892393Syz155240 int v, atype;
9902393Syz155240 void *ifptr;
9912393Syz155240 struct in_addr *inp, *inpmask;
9923448Sdh155122 ipf_stack_t *ifs;
9932393Syz155240 {
9942393Syz155240 	struct ifnet *ifp = ifptr;
9952393Syz155240 #ifdef __sgi
9962393Syz155240 	struct in_ifaddr *ifa;
9972393Syz155240 #else
9982393Syz155240 	struct ifaddr *ifa;
9992393Syz155240 #endif
10002393Syz155240 
10012393Syz155240 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
10022393Syz155240 	ifa = ifp->if_addrlist.tqh_first;
10032393Syz155240 #else
10042393Syz155240 # ifdef __sgi
10052393Syz155240 	ifa = (struct in_ifaddr *)ifp->in_ifaddr;
10062393Syz155240 # else
10072393Syz155240 	ifa = ifp->if_addrlist;
10082393Syz155240 # endif
10092393Syz155240 #endif
10102393Syz155240 	if (ifa != NULL) {
10112393Syz155240 		struct sockaddr_in *sin, mask;
10122393Syz155240 
10132393Syz155240 		mask.sin_addr.s_addr = 0xffffffff;
10142393Syz155240 
10152393Syz155240 #ifdef __sgi
10162393Syz155240 		sin = (struct sockaddr_in *)&ifa->ia_addr;
10172393Syz155240 #else
10182393Syz155240 		sin = (struct sockaddr_in *)&ifa->ifa_addr;
10192393Syz155240 #endif
10202393Syz155240 
10212393Syz155240 		return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask);
10222393Syz155240 	}
10232393Syz155240 	return 0;
10242393Syz155240 }
10257259Sdr146992 
10267259Sdr146992 
10277259Sdr146992 /*
10287259Sdr146992  * This function is not meant to be random, rather just produce a
10297259Sdr146992  * sequence of numbers that isn't linear to show "randomness".
10307259Sdr146992  */
ipf_random()10317259Sdr146992 u_32_t ipf_random()
10327259Sdr146992 {
10337259Sdr146992 	static u_int last = 0xa5a5a5a5;
10347259Sdr146992 	static int calls = 0;
10357259Sdr146992 	int number;
10367259Sdr146992 
10377259Sdr146992 	calls++;
10387259Sdr146992 
10397259Sdr146992 	/*
10407259Sdr146992 	 * These are deliberately chosen to ensure that there is some
10417259Sdr146992 	 * attempt to test whether the output covers the range in test n18.
10427259Sdr146992 	 */
10437259Sdr146992 	switch (calls)
10447259Sdr146992 	{
10457259Sdr146992 	case 1 :
10467259Sdr146992 		number = 0;
10477259Sdr146992 		break;
10487259Sdr146992 	case 2 :
10497259Sdr146992 		number = 4;
10507259Sdr146992 		break;
10517259Sdr146992 	case 3 :
10527259Sdr146992 		number = 3999;
10537259Sdr146992 		break;
10547259Sdr146992 	case 4 :
10557259Sdr146992 		number = 4000;
10567259Sdr146992 		break;
10577259Sdr146992 	case 5 :
10587259Sdr146992 		number = 48999;
10597259Sdr146992 		break;
10607259Sdr146992 	case 6 :
10617259Sdr146992 		number = 49000;
10627259Sdr146992 		break;
10637259Sdr146992 	default :
10647259Sdr146992 		number = last;
10657259Sdr146992 		last *= calls;
10667259Sdr146992 		last++;
10677259Sdr146992 		number ^= last;
10687259Sdr146992 		break;
10697259Sdr146992 	}
10707259Sdr146992 	return number;
10717259Sdr146992 }
1072