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