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*ab25eeb5Syz * Copyright 2006 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) 13*ab25eeb5Syz static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 14*ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.9 2005/01/08 14:22:18 darrenr Exp $"; 157c478bd9Sstevel@tonic-gate #endif 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate #ifndef SOLARIS 187c478bd9Sstevel@tonic-gate #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 197c478bd9Sstevel@tonic-gate #endif 207c478bd9Sstevel@tonic-gate 217c478bd9Sstevel@tonic-gate #include <sys/param.h> 227c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__) && !defined(__FreeBSD_version) 237c478bd9Sstevel@tonic-gate # if defined(IPFILTER_LKM) 247c478bd9Sstevel@tonic-gate # ifndef __FreeBSD_cc_version 257c478bd9Sstevel@tonic-gate # include <osreldate.h> 267c478bd9Sstevel@tonic-gate # else 277c478bd9Sstevel@tonic-gate # if __FreeBSD_cc_version < 430000 287c478bd9Sstevel@tonic-gate # include <osreldate.h> 297c478bd9Sstevel@tonic-gate # endif 307c478bd9Sstevel@tonic-gate # endif 317c478bd9Sstevel@tonic-gate # endif 327c478bd9Sstevel@tonic-gate #endif 337c478bd9Sstevel@tonic-gate #include <sys/errno.h> 34*ab25eeb5Syz #if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) 35*ab25eeb5Syz # include <sys/kern_svcs.h> 36*ab25eeb5Syz #endif 377c478bd9Sstevel@tonic-gate #include <sys/types.h> 38*ab25eeb5Syz #define _KERNEL 39*ab25eeb5Syz #define KERNEL 40*ab25eeb5Syz #ifdef __OpenBSD__ 417c478bd9Sstevel@tonic-gate struct file; 427c478bd9Sstevel@tonic-gate #endif 43*ab25eeb5Syz #include <sys/uio.h> 44*ab25eeb5Syz #undef _KERNEL 45*ab25eeb5Syz #undef KERNEL 467c478bd9Sstevel@tonic-gate #include <sys/file.h> 477c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 487c478bd9Sstevel@tonic-gate #ifdef __sgi 497c478bd9Sstevel@tonic-gate # include <sys/ptimers.h> 507c478bd9Sstevel@tonic-gate #endif 517c478bd9Sstevel@tonic-gate #include <sys/time.h> 527c478bd9Sstevel@tonic-gate #if !SOLARIS 537c478bd9Sstevel@tonic-gate # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) 547c478bd9Sstevel@tonic-gate # include <sys/dirent.h> 557c478bd9Sstevel@tonic-gate # else 567c478bd9Sstevel@tonic-gate # include <sys/dir.h> 577c478bd9Sstevel@tonic-gate # endif 587c478bd9Sstevel@tonic-gate #else 597c478bd9Sstevel@tonic-gate # include <sys/filio.h> 607c478bd9Sstevel@tonic-gate #endif 61*ab25eeb5Syz #ifndef linux 62*ab25eeb5Syz # include <sys/protosw.h> 63*ab25eeb5Syz #endif 647c478bd9Sstevel@tonic-gate #include <sys/socket.h> 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #include <stdio.h> 677c478bd9Sstevel@tonic-gate #include <string.h> 687c478bd9Sstevel@tonic-gate #include <stdlib.h> 697c478bd9Sstevel@tonic-gate #include <ctype.h> 707c478bd9Sstevel@tonic-gate #include <fcntl.h> 71*ab25eeb5Syz #include <arpa/inet.h> 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #ifdef __hpux 747c478bd9Sstevel@tonic-gate # define _NET_ROUTE_INCLUDED 757c478bd9Sstevel@tonic-gate #endif 767c478bd9Sstevel@tonic-gate #include <net/if.h> 777c478bd9Sstevel@tonic-gate #ifdef sun 787c478bd9Sstevel@tonic-gate # include <net/af.h> 797c478bd9Sstevel@tonic-gate #endif 807c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000 817c478bd9Sstevel@tonic-gate # include <net/if_var.h> 827c478bd9Sstevel@tonic-gate #endif 837c478bd9Sstevel@tonic-gate #ifdef __sgi 847c478bd9Sstevel@tonic-gate #include <sys/debug.h> 857c478bd9Sstevel@tonic-gate # ifdef IFF_DRVRLOCK /* IRIX6 */ 867c478bd9Sstevel@tonic-gate #include <sys/hashing.h> 877c478bd9Sstevel@tonic-gate # endif 887c478bd9Sstevel@tonic-gate #endif 89*ab25eeb5Syz #if defined(__FreeBSD__) 90*ab25eeb5Syz # include "radix_ipf.h" 91*ab25eeb5Syz #endif 927c478bd9Sstevel@tonic-gate #include <net/route.h> 937c478bd9Sstevel@tonic-gate #include <netinet/in.h> 947c478bd9Sstevel@tonic-gate #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \ 95*ab25eeb5Syz !defined(__hpux) && !defined(linux) 967c478bd9Sstevel@tonic-gate # include <netinet/in_var.h> 977c478bd9Sstevel@tonic-gate #endif 987c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 997c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 100*ab25eeb5Syz #if !defined(linux) 101*ab25eeb5Syz # include <netinet/ip_var.h> 102*ab25eeb5Syz #endif 1037c478bd9Sstevel@tonic-gate #include <netinet/tcp.h> 1047c478bd9Sstevel@tonic-gate #if defined(__osf__) 1057c478bd9Sstevel@tonic-gate # include <netinet/tcp_timer.h> 1067c478bd9Sstevel@tonic-gate #endif 107*ab25eeb5Syz #if defined(__osf__) || defined(__hpux) || defined(__sgi) 108*ab25eeb5Syz # include "radix_ipf_local.h" 109*ab25eeb5Syz # define _RADIX_H_ 110*ab25eeb5Syz #endif 1117c478bd9Sstevel@tonic-gate #include <netinet/udp.h> 1127c478bd9Sstevel@tonic-gate #include <netinet/tcpip.h> 1137c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h> 1147c478bd9Sstevel@tonic-gate #include <unistd.h> 1157c478bd9Sstevel@tonic-gate #include <syslog.h> 1167c478bd9Sstevel@tonic-gate #ifdef __hpux 1177c478bd9Sstevel@tonic-gate # undef _NET_ROUTE_INCLUDED 1187c478bd9Sstevel@tonic-gate #endif 1197c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h" 1207c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h" 1217c478bd9Sstevel@tonic-gate #include "netinet/ip_nat.h" 1227c478bd9Sstevel@tonic-gate #include "netinet/ip_frag.h" 1237c478bd9Sstevel@tonic-gate #include "netinet/ip_state.h" 1247c478bd9Sstevel@tonic-gate #include "netinet/ip_proxy.h" 1257c478bd9Sstevel@tonic-gate #include "netinet/ip_auth.h" 1267c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SYNC 1277c478bd9Sstevel@tonic-gate #include "netinet/ip_sync.h" 1287c478bd9Sstevel@tonic-gate #endif 1297c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SCAN 1307c478bd9Sstevel@tonic-gate #include "netinet/ip_scan.h" 1317c478bd9Sstevel@tonic-gate #endif 1327c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h" 1337c478bd9Sstevel@tonic-gate #ifdef IPFILTER_COMPILED 1347c478bd9Sstevel@tonic-gate # include "netinet/ip_rules.h" 1357c478bd9Sstevel@tonic-gate #endif 1367c478bd9Sstevel@tonic-gate #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 1377c478bd9Sstevel@tonic-gate # include <sys/malloc.h> 1387c478bd9Sstevel@tonic-gate #endif 1397c478bd9Sstevel@tonic-gate #ifdef __hpux 1407c478bd9Sstevel@tonic-gate struct rtentry; 1417c478bd9Sstevel@tonic-gate #endif 142*ab25eeb5Syz #include "md5.h" 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate #if !defined(__osf__) 1467c478bd9Sstevel@tonic-gate extern struct protosw inetsw[]; 1477c478bd9Sstevel@tonic-gate #endif 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate #include "ipt.h" 1507c478bd9Sstevel@tonic-gate static struct ifnet **ifneta = NULL; 1517c478bd9Sstevel@tonic-gate static int nifs = 0; 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate static int frzerostats __P((caddr_t)); 154*ab25eeb5Syz static void fr_setifpaddr __P((struct ifnet *, char *)); 1557c478bd9Sstevel@tonic-gate void init_ifp __P((void)); 156*ab25eeb5Syz #if defined(__sgi) && (IRIX < 60500) 1577c478bd9Sstevel@tonic-gate static int no_output __P((struct ifnet *, struct mbuf *, 1587c478bd9Sstevel@tonic-gate struct sockaddr *)); 1597c478bd9Sstevel@tonic-gate static int write_output __P((struct ifnet *, struct mbuf *, 1607c478bd9Sstevel@tonic-gate struct sockaddr *)); 1617c478bd9Sstevel@tonic-gate #else 1627c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 1637c478bd9Sstevel@tonic-gate static int no_output __P((struct ifnet *, struct mbuf *, 1647c478bd9Sstevel@tonic-gate struct sockaddr *, struct rtentry *, char *)); 1657c478bd9Sstevel@tonic-gate static int write_output __P((struct ifnet *, struct mbuf *, 1667c478bd9Sstevel@tonic-gate struct sockaddr *, struct rtentry *, char *)); 1677c478bd9Sstevel@tonic-gate # else 1687c478bd9Sstevel@tonic-gate static int no_output __P((struct ifnet *, struct mbuf *, 1697c478bd9Sstevel@tonic-gate struct sockaddr *, struct rtentry *)); 1707c478bd9Sstevel@tonic-gate static int write_output __P((struct ifnet *, struct mbuf *, 1717c478bd9Sstevel@tonic-gate struct sockaddr *, struct rtentry *)); 1727c478bd9Sstevel@tonic-gate # endif 1737c478bd9Sstevel@tonic-gate #endif 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate int iplattach() 1777c478bd9Sstevel@tonic-gate { 1787c478bd9Sstevel@tonic-gate fr_running = 1; 1797c478bd9Sstevel@tonic-gate return 0; 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate int ipldetach() 1847c478bd9Sstevel@tonic-gate { 1857c478bd9Sstevel@tonic-gate fr_running = -1; 1867c478bd9Sstevel@tonic-gate return 0; 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate static int frzerostats(data) 1917c478bd9Sstevel@tonic-gate caddr_t data; 1927c478bd9Sstevel@tonic-gate { 1937c478bd9Sstevel@tonic-gate friostat_t fio; 1947c478bd9Sstevel@tonic-gate int error; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate fr_getstat(&fio); 1977c478bd9Sstevel@tonic-gate error = copyoutptr(&fio, data, sizeof(fio)); 1987c478bd9Sstevel@tonic-gate if (error) 1997c478bd9Sstevel@tonic-gate return EFAULT; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate bzero((char *)frstats, sizeof(*frstats) * 2); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate return 0; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* 2087c478bd9Sstevel@tonic-gate * Filter ioctl interface. 2097c478bd9Sstevel@tonic-gate */ 2107c478bd9Sstevel@tonic-gate int iplioctl(dev, cmd, data, mode) 2117c478bd9Sstevel@tonic-gate int dev; 212*ab25eeb5Syz ioctlcmd_t cmd; 2137c478bd9Sstevel@tonic-gate caddr_t data; 2147c478bd9Sstevel@tonic-gate int mode; 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate int error = 0, unit = 0, tmp; 2177c478bd9Sstevel@tonic-gate friostat_t fio; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate unit = dev; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate SPL_NET(s); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate if (unit == IPL_LOGNAT) { 2247c478bd9Sstevel@tonic-gate if (fr_running > 0) 2257c478bd9Sstevel@tonic-gate error = fr_nat_ioctl(data, cmd, mode); 2267c478bd9Sstevel@tonic-gate else 2277c478bd9Sstevel@tonic-gate error = EIO; 2287c478bd9Sstevel@tonic-gate SPL_X(s); 2297c478bd9Sstevel@tonic-gate return error; 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate if (unit == IPL_LOGSTATE) { 2327c478bd9Sstevel@tonic-gate if (fr_running > 0) 2337c478bd9Sstevel@tonic-gate error = fr_state_ioctl(data, cmd, mode); 2347c478bd9Sstevel@tonic-gate else 2357c478bd9Sstevel@tonic-gate error = EIO; 2367c478bd9Sstevel@tonic-gate SPL_X(s); 2377c478bd9Sstevel@tonic-gate return error; 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate if (unit == IPL_LOGAUTH) { 2407c478bd9Sstevel@tonic-gate if (fr_running > 0) { 241*ab25eeb5Syz if ((cmd == (ioctlcmd_t)SIOCADAFR) || 242*ab25eeb5Syz (cmd == (ioctlcmd_t)SIOCRMAFR)) { 2437c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) { 2447c478bd9Sstevel@tonic-gate error = EPERM; 2457c478bd9Sstevel@tonic-gate } else { 2467c478bd9Sstevel@tonic-gate error = frrequest(unit, cmd, data, 2477c478bd9Sstevel@tonic-gate fr_active, 1); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate } else { 2507c478bd9Sstevel@tonic-gate error = fr_auth_ioctl(data, mode, cmd); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate } else 2537c478bd9Sstevel@tonic-gate error = EIO; 2547c478bd9Sstevel@tonic-gate SPL_X(s); 2557c478bd9Sstevel@tonic-gate return error; 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate if (unit == IPL_LOGSYNC) { 2587c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SYNC 2597c478bd9Sstevel@tonic-gate if (fr_running > 0) 2607c478bd9Sstevel@tonic-gate error = fr_sync_ioctl(data, cmd, mode); 2617c478bd9Sstevel@tonic-gate else 2627c478bd9Sstevel@tonic-gate #endif 2637c478bd9Sstevel@tonic-gate error = EIO; 2647c478bd9Sstevel@tonic-gate SPL_X(s); 2657c478bd9Sstevel@tonic-gate return error; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate if (unit == IPL_LOGSCAN) { 2687c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SCAN 2697c478bd9Sstevel@tonic-gate if (fr_running > 0) 2707c478bd9Sstevel@tonic-gate error = fr_scan_ioctl(data, cmd, mode); 2717c478bd9Sstevel@tonic-gate else 2727c478bd9Sstevel@tonic-gate #endif 2737c478bd9Sstevel@tonic-gate error = EIO; 2747c478bd9Sstevel@tonic-gate SPL_X(s); 2757c478bd9Sstevel@tonic-gate return error; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate if (unit == IPL_LOGLOOKUP) { 2787c478bd9Sstevel@tonic-gate if (fr_running > 0) 2797c478bd9Sstevel@tonic-gate error = ip_lookup_ioctl(data, cmd, mode); 2807c478bd9Sstevel@tonic-gate else 2817c478bd9Sstevel@tonic-gate error = EIO; 2827c478bd9Sstevel@tonic-gate SPL_X(s); 2837c478bd9Sstevel@tonic-gate return error; 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate switch (cmd) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate case FIONREAD : 2897c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOG 2907c478bd9Sstevel@tonic-gate error = COPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data, 2917c478bd9Sstevel@tonic-gate sizeof(iplused[IPL_LOGIPF])); 2927c478bd9Sstevel@tonic-gate #endif 2937c478bd9Sstevel@tonic-gate break; 2947c478bd9Sstevel@tonic-gate case SIOCFRENB : 2957c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 2967c478bd9Sstevel@tonic-gate error = EPERM; 2977c478bd9Sstevel@tonic-gate else { 2987c478bd9Sstevel@tonic-gate error = COPYIN(data, &tmp, sizeof(tmp)); 2997c478bd9Sstevel@tonic-gate if (error) 3007c478bd9Sstevel@tonic-gate break; 3017c478bd9Sstevel@tonic-gate if (tmp) 3027c478bd9Sstevel@tonic-gate error = iplattach(); 3037c478bd9Sstevel@tonic-gate else 3047c478bd9Sstevel@tonic-gate error = ipldetach(); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate break; 307*ab25eeb5Syz case SIOCIPFSET : 308*ab25eeb5Syz if (!(mode & FWRITE)) { 309*ab25eeb5Syz error = EPERM; 310*ab25eeb5Syz break; 311*ab25eeb5Syz } 312*ab25eeb5Syz case SIOCIPFGETNEXT : 313*ab25eeb5Syz case SIOCIPFGET : 314*ab25eeb5Syz error = fr_ipftune(cmd, (void *)data); 315*ab25eeb5Syz break; 3167c478bd9Sstevel@tonic-gate case SIOCSETFF : 3177c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3187c478bd9Sstevel@tonic-gate error = EPERM; 3197c478bd9Sstevel@tonic-gate else 3207c478bd9Sstevel@tonic-gate error = COPYIN(data, &fr_flags, sizeof(fr_flags)); 3217c478bd9Sstevel@tonic-gate break; 3227c478bd9Sstevel@tonic-gate case SIOCGETFF : 3237c478bd9Sstevel@tonic-gate error = COPYOUT(&fr_flags, data, sizeof(fr_flags)); 3247c478bd9Sstevel@tonic-gate break; 3257c478bd9Sstevel@tonic-gate case SIOCFUNCL : 3267c478bd9Sstevel@tonic-gate error = fr_resolvefunc(data); 3277c478bd9Sstevel@tonic-gate break; 3287c478bd9Sstevel@tonic-gate case SIOCINAFR : 3297c478bd9Sstevel@tonic-gate case SIOCRMAFR : 3307c478bd9Sstevel@tonic-gate case SIOCADAFR : 3317c478bd9Sstevel@tonic-gate case SIOCZRLST : 3327c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3337c478bd9Sstevel@tonic-gate error = EPERM; 3347c478bd9Sstevel@tonic-gate else 3357c478bd9Sstevel@tonic-gate error = frrequest(unit, cmd, data, fr_active, 1); 3367c478bd9Sstevel@tonic-gate break; 3377c478bd9Sstevel@tonic-gate case SIOCINIFR : 3387c478bd9Sstevel@tonic-gate case SIOCRMIFR : 3397c478bd9Sstevel@tonic-gate case SIOCADIFR : 3407c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3417c478bd9Sstevel@tonic-gate error = EPERM; 3427c478bd9Sstevel@tonic-gate else 3437c478bd9Sstevel@tonic-gate error = frrequest(unit, cmd, data, 1 - fr_active, 1); 3447c478bd9Sstevel@tonic-gate break; 3457c478bd9Sstevel@tonic-gate case SIOCSWAPA : 3467c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3477c478bd9Sstevel@tonic-gate error = EPERM; 3487c478bd9Sstevel@tonic-gate else { 3497c478bd9Sstevel@tonic-gate bzero((char *)frcache, sizeof(frcache[0]) * 2); 3507c478bd9Sstevel@tonic-gate *(u_int *)data = fr_active; 3517c478bd9Sstevel@tonic-gate fr_active = 1 - fr_active; 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate break; 3547c478bd9Sstevel@tonic-gate case SIOCGETFS : 3557c478bd9Sstevel@tonic-gate fr_getstat(&fio); 3567c478bd9Sstevel@tonic-gate error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); 3577c478bd9Sstevel@tonic-gate break; 3587c478bd9Sstevel@tonic-gate case SIOCFRZST : 3597c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3607c478bd9Sstevel@tonic-gate error = EPERM; 3617c478bd9Sstevel@tonic-gate else 3627c478bd9Sstevel@tonic-gate error = frzerostats(data); 3637c478bd9Sstevel@tonic-gate break; 3647c478bd9Sstevel@tonic-gate case SIOCIPFFL : 3657c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3667c478bd9Sstevel@tonic-gate error = EPERM; 3677c478bd9Sstevel@tonic-gate else { 3687c478bd9Sstevel@tonic-gate error = COPYIN(data, &tmp, sizeof(tmp)); 3697c478bd9Sstevel@tonic-gate if (!error) { 3707663b816Sml tmp = frflush(unit, 4, tmp); 3717c478bd9Sstevel@tonic-gate error = COPYOUT(&tmp, data, sizeof(tmp)); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate break; 3757663b816Sml #ifdef USE_INET6 3767663b816Sml case SIOCIPFL6 : 3777663b816Sml if (!(mode & FWRITE)) 3787663b816Sml error = EPERM; 3797663b816Sml else { 3807663b816Sml error = COPYIN(data, &tmp, sizeof(tmp)); 3817663b816Sml if (!error) { 3827663b816Sml tmp = frflush(unit, 6, tmp); 3837663b816Sml error = COPYOUT(&tmp, data, sizeof(tmp)); 3847663b816Sml } 3857663b816Sml } 3867663b816Sml break; 3877663b816Sml #endif 3887c478bd9Sstevel@tonic-gate case SIOCSTLCK : 3897c478bd9Sstevel@tonic-gate error = COPYIN(data, &tmp, sizeof(tmp)); 3907c478bd9Sstevel@tonic-gate if (error == 0) { 3917c478bd9Sstevel@tonic-gate fr_state_lock = tmp; 3927c478bd9Sstevel@tonic-gate fr_nat_lock = tmp; 3937c478bd9Sstevel@tonic-gate fr_frag_lock = tmp; 3947c478bd9Sstevel@tonic-gate fr_auth_lock = tmp; 3957c478bd9Sstevel@tonic-gate } else 3967c478bd9Sstevel@tonic-gate error = EFAULT; 3977c478bd9Sstevel@tonic-gate break; 3987c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOG 3997c478bd9Sstevel@tonic-gate case SIOCIPFFB : 4007c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 4017c478bd9Sstevel@tonic-gate error = EPERM; 4027c478bd9Sstevel@tonic-gate else 4037c478bd9Sstevel@tonic-gate *(int *)data = ipflog_clear(unit); 4047c478bd9Sstevel@tonic-gate break; 4057c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOG */ 4067c478bd9Sstevel@tonic-gate case SIOCGFRST : 4077c478bd9Sstevel@tonic-gate error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); 4087c478bd9Sstevel@tonic-gate break; 4097c478bd9Sstevel@tonic-gate case SIOCFRSYN : 4107c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 4117c478bd9Sstevel@tonic-gate error = EPERM; 4127c478bd9Sstevel@tonic-gate else { 413*ab25eeb5Syz frsync(NULL); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate break; 4167c478bd9Sstevel@tonic-gate default : 4177c478bd9Sstevel@tonic-gate error = EINVAL; 4187c478bd9Sstevel@tonic-gate break; 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate SPL_X(s); 4217c478bd9Sstevel@tonic-gate return error; 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate void fr_forgetifp(ifp) 4267c478bd9Sstevel@tonic-gate void *ifp; 4277c478bd9Sstevel@tonic-gate { 4287c478bd9Sstevel@tonic-gate register frentry_t *f; 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate WRITE_ENTER(&ipf_mutex); 4317c478bd9Sstevel@tonic-gate for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) 4327c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4337c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4347c478bd9Sstevel@tonic-gate for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) 4357c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4367c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4377c478bd9Sstevel@tonic-gate for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) 4387c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4397c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4407c478bd9Sstevel@tonic-gate for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) 4417c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4427c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4437c478bd9Sstevel@tonic-gate #ifdef USE_INET6 4447c478bd9Sstevel@tonic-gate for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) 4457c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4467c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4477c478bd9Sstevel@tonic-gate for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) 4487c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4497c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4507c478bd9Sstevel@tonic-gate for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) 4517c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4527c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4537c478bd9Sstevel@tonic-gate for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) 4547c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4557c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4567c478bd9Sstevel@tonic-gate #endif 4577c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ipf_mutex); 4587c478bd9Sstevel@tonic-gate fr_natsync(ifp); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate 462*ab25eeb5Syz void fr_resolvedest(fdp, v) 4637c478bd9Sstevel@tonic-gate frdest_t *fdp; 4647c478bd9Sstevel@tonic-gate int v; 4657c478bd9Sstevel@tonic-gate { 4667c478bd9Sstevel@tonic-gate fdp->fd_ifp = NULL; 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate if (*fdp->fd_ifname) { 4697c478bd9Sstevel@tonic-gate fdp->fd_ifp = GETIFP(fdp->fd_ifname, v); 4707c478bd9Sstevel@tonic-gate if (!fdp->fd_ifp) 4717c478bd9Sstevel@tonic-gate fdp->fd_ifp = (struct ifnet *)-1; 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate 476*ab25eeb5Syz #if defined(__sgi) && (IRIX < 60500) 4777c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s) 4787c478bd9Sstevel@tonic-gate #else 4797c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 4807c478bd9Sstevel@tonic-gate static int no_output (ifp, m, s, rt, cp) 4817c478bd9Sstevel@tonic-gate char *cp; 4827c478bd9Sstevel@tonic-gate # else 4837c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s, rt) 4847c478bd9Sstevel@tonic-gate # endif 4857c478bd9Sstevel@tonic-gate struct rtentry *rt; 4867c478bd9Sstevel@tonic-gate #endif 4877c478bd9Sstevel@tonic-gate struct ifnet *ifp; 4887c478bd9Sstevel@tonic-gate struct mbuf *m; 4897c478bd9Sstevel@tonic-gate struct sockaddr *s; 4907c478bd9Sstevel@tonic-gate { 4917c478bd9Sstevel@tonic-gate return 0; 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate 495*ab25eeb5Syz #if defined(__sgi) && (IRIX < 60500) 4967c478bd9Sstevel@tonic-gate static int write_output(ifp, m, s) 4977c478bd9Sstevel@tonic-gate #else 4987c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 4997c478bd9Sstevel@tonic-gate static int write_output (ifp, m, s, rt, cp) 5007c478bd9Sstevel@tonic-gate char *cp; 5017c478bd9Sstevel@tonic-gate # else 5027c478bd9Sstevel@tonic-gate static int write_output(ifp, m, s, rt) 5037c478bd9Sstevel@tonic-gate # endif 5047c478bd9Sstevel@tonic-gate struct rtentry *rt; 5057c478bd9Sstevel@tonic-gate #endif 5067c478bd9Sstevel@tonic-gate struct ifnet *ifp; 5077c478bd9Sstevel@tonic-gate struct mbuf *m; 5087c478bd9Sstevel@tonic-gate struct sockaddr *s; 5097c478bd9Sstevel@tonic-gate { 5107c478bd9Sstevel@tonic-gate char fname[32]; 5117c478bd9Sstevel@tonic-gate mb_t *mb; 5127c478bd9Sstevel@tonic-gate ip_t *ip; 5137c478bd9Sstevel@tonic-gate int fd; 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate mb = (mb_t *)m; 5167c478bd9Sstevel@tonic-gate ip = MTOD(mb, ip_t *); 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 519*ab25eeb5Syz (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 520*ab25eeb5Syz (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 5217c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s", ifp->if_xname); 5227c478bd9Sstevel@tonic-gate #else 5237c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 5247c478bd9Sstevel@tonic-gate #endif 5257c478bd9Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_APPEND); 5267c478bd9Sstevel@tonic-gate if (fd == -1) { 5277c478bd9Sstevel@tonic-gate perror("open"); 5287c478bd9Sstevel@tonic-gate return -1; 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate write(fd, (char *)ip, ntohs(ip->ip_len)); 5317c478bd9Sstevel@tonic-gate close(fd); 5327c478bd9Sstevel@tonic-gate return 0; 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate 536*ab25eeb5Syz static void fr_setifpaddr(ifp, addr) 537*ab25eeb5Syz struct ifnet *ifp; 538*ab25eeb5Syz char *addr; 539*ab25eeb5Syz { 540*ab25eeb5Syz #ifdef __sgi 541*ab25eeb5Syz struct in_ifaddr *ifa; 542*ab25eeb5Syz #else 543*ab25eeb5Syz struct ifaddr *ifa; 544*ab25eeb5Syz #endif 545*ab25eeb5Syz 546*ab25eeb5Syz #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 547*ab25eeb5Syz if (ifp->if_addrlist.tqh_first != NULL) 548*ab25eeb5Syz #else 549*ab25eeb5Syz # ifdef __sgi 550*ab25eeb5Syz if (ifp->in_ifaddr != NULL) 551*ab25eeb5Syz # else 552*ab25eeb5Syz if (ifp->if_addrlist != NULL) 553*ab25eeb5Syz # endif 554*ab25eeb5Syz #endif 555*ab25eeb5Syz return; 556*ab25eeb5Syz 557*ab25eeb5Syz ifa = (struct ifaddr *)malloc(sizeof(*ifa)); 558*ab25eeb5Syz #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 559*ab25eeb5Syz ifp->if_addrlist.tqh_first = ifa; 560*ab25eeb5Syz #else 561*ab25eeb5Syz # ifdef __sgi 562*ab25eeb5Syz ifp->in_ifaddr = ifa; 563*ab25eeb5Syz # else 564*ab25eeb5Syz ifp->if_addrlist = ifa; 565*ab25eeb5Syz # endif 566*ab25eeb5Syz #endif 567*ab25eeb5Syz 568*ab25eeb5Syz if (ifa != NULL) { 569*ab25eeb5Syz struct sockaddr_in *sin; 570*ab25eeb5Syz 571*ab25eeb5Syz #ifdef __sgi 572*ab25eeb5Syz sin = (struct sockaddr_in *)&ifa->ia_addr; 573*ab25eeb5Syz #else 574*ab25eeb5Syz sin = (struct sockaddr_in *)&ifa->ifa_addr; 575*ab25eeb5Syz #endif 576*ab25eeb5Syz sin->sin_addr.s_addr = inet_addr(addr); 577*ab25eeb5Syz if (sin->sin_addr.s_addr == 0) 578*ab25eeb5Syz abort(); 579*ab25eeb5Syz } 580*ab25eeb5Syz } 581*ab25eeb5Syz 5827c478bd9Sstevel@tonic-gate struct ifnet *get_unit(name, v) 5837c478bd9Sstevel@tonic-gate char *name; 5847c478bd9Sstevel@tonic-gate int v; 5857c478bd9Sstevel@tonic-gate { 586*ab25eeb5Syz struct ifnet *ifp, **ifpp, **old_ifneta; 587*ab25eeb5Syz char *addr; 5887c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 589*ab25eeb5Syz (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 590*ab25eeb5Syz (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate if (name == NULL) 5937c478bd9Sstevel@tonic-gate name = "anon0"; 5947c478bd9Sstevel@tonic-gate 595*ab25eeb5Syz addr = strchr(name, '='); 596*ab25eeb5Syz if (addr != NULL) 597*ab25eeb5Syz *addr++ = '\0'; 598*ab25eeb5Syz 599*ab25eeb5Syz for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 600*ab25eeb5Syz if (!strcmp(name, ifp->if_xname)) { 601*ab25eeb5Syz if (addr != NULL) 602*ab25eeb5Syz fr_setifpaddr(ifp, addr); 6037c478bd9Sstevel@tonic-gate return ifp; 604*ab25eeb5Syz } 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate #else 6077c478bd9Sstevel@tonic-gate char *s, ifname[LIFNAMSIZ+1]; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate if (name == NULL) 6107c478bd9Sstevel@tonic-gate name = "anon0"; 6117c478bd9Sstevel@tonic-gate 612*ab25eeb5Syz addr = strchr(name, '='); 613*ab25eeb5Syz if (addr != NULL) 614*ab25eeb5Syz *addr++ = '\0'; 615*ab25eeb5Syz 616*ab25eeb5Syz for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 6177c478bd9Sstevel@tonic-gate COPYIFNAME(ifp, ifname); 618*ab25eeb5Syz if (!strcmp(name, ifname)) { 619*ab25eeb5Syz if (addr != NULL) 620*ab25eeb5Syz fr_setifpaddr(ifp, addr); 6217c478bd9Sstevel@tonic-gate return ifp; 622*ab25eeb5Syz } 6237c478bd9Sstevel@tonic-gate } 6247c478bd9Sstevel@tonic-gate #endif 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate if (!ifneta) { 6277c478bd9Sstevel@tonic-gate ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 6287c478bd9Sstevel@tonic-gate if (!ifneta) 6297c478bd9Sstevel@tonic-gate return NULL; 6307c478bd9Sstevel@tonic-gate ifneta[1] = NULL; 6317c478bd9Sstevel@tonic-gate ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 6327c478bd9Sstevel@tonic-gate if (!ifneta[0]) { 6337c478bd9Sstevel@tonic-gate free(ifneta); 6347c478bd9Sstevel@tonic-gate return NULL; 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate nifs = 1; 6377c478bd9Sstevel@tonic-gate } else { 6387c478bd9Sstevel@tonic-gate old_ifneta = ifneta; 6397c478bd9Sstevel@tonic-gate nifs++; 6407c478bd9Sstevel@tonic-gate ifneta = (struct ifnet **)realloc(ifneta, 641*ab25eeb5Syz (nifs + 1) * sizeof(ifp)); 6427c478bd9Sstevel@tonic-gate if (!ifneta) { 6437c478bd9Sstevel@tonic-gate free(old_ifneta); 6447c478bd9Sstevel@tonic-gate nifs = 0; 6457c478bd9Sstevel@tonic-gate return NULL; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate ifneta[nifs] = NULL; 6487c478bd9Sstevel@tonic-gate ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 6497c478bd9Sstevel@tonic-gate if (!ifneta[nifs - 1]) { 6507c478bd9Sstevel@tonic-gate nifs--; 6517c478bd9Sstevel@tonic-gate return NULL; 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate ifp = ifneta[nifs - 1]; 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 657*ab25eeb5Syz (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 658*ab25eeb5Syz (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 659*ab25eeb5Syz (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 6607c478bd9Sstevel@tonic-gate #else 661*ab25eeb5Syz for (s = name; *s && !ISDIGIT(*s); s++) 6627c478bd9Sstevel@tonic-gate ; 663*ab25eeb5Syz if (*s && ISDIGIT(*s)) { 6647c478bd9Sstevel@tonic-gate ifp->if_unit = atoi(s); 6657c478bd9Sstevel@tonic-gate ifp->if_name = (char *)malloc(s - name + 1); 6665e985db5Sschuster if (ifp->if_name == NULL) { 6675e985db5Sschuster /* 6685e985db5Sschuster * XXX do it more elegantly: free up mem, 6695e985db5Sschuster * return NULL 6705e985db5Sschuster */ 6715e985db5Sschuster perror("malloc"); 6725e985db5Sschuster exit(1); 6735e985db5Sschuster } 674*ab25eeb5Syz (void) strncpy(ifp->if_name, name, s - name); 6757c478bd9Sstevel@tonic-gate ifp->if_name[s - name] = '\0'; 6767c478bd9Sstevel@tonic-gate } else { 6777c478bd9Sstevel@tonic-gate ifp->if_name = strdup(name); 6787c478bd9Sstevel@tonic-gate ifp->if_unit = -1; 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate #endif 6817c478bd9Sstevel@tonic-gate ifp->if_output = no_output; 682*ab25eeb5Syz 683*ab25eeb5Syz if (addr != NULL) { 684*ab25eeb5Syz fr_setifpaddr(ifp, addr); 685*ab25eeb5Syz } 686*ab25eeb5Syz 6877c478bd9Sstevel@tonic-gate return ifp; 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate char *get_ifname(ifp) 6927c478bd9Sstevel@tonic-gate struct ifnet *ifp; 6937c478bd9Sstevel@tonic-gate { 6947c478bd9Sstevel@tonic-gate static char ifname[LIFNAMSIZ]; 6957c478bd9Sstevel@tonic-gate 696*ab25eeb5Syz #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \ 697*ab25eeb5Syz (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 6987c478bd9Sstevel@tonic-gate sprintf(ifname, "%s", ifp->if_xname); 6997c478bd9Sstevel@tonic-gate #else 7007c478bd9Sstevel@tonic-gate sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 7017c478bd9Sstevel@tonic-gate #endif 7027c478bd9Sstevel@tonic-gate return ifname; 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate void init_ifp() 7087c478bd9Sstevel@tonic-gate { 709*ab25eeb5Syz struct ifnet *ifp, **ifpp; 7107c478bd9Sstevel@tonic-gate char fname[32]; 7117c478bd9Sstevel@tonic-gate int fd; 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 714*ab25eeb5Syz (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 715*ab25eeb5Syz (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 716*ab25eeb5Syz for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 7177c478bd9Sstevel@tonic-gate ifp->if_output = write_output; 7187c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s", ifp->if_xname); 7197c478bd9Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 7207c478bd9Sstevel@tonic-gate if (fd == -1) 7217c478bd9Sstevel@tonic-gate perror("open"); 7227c478bd9Sstevel@tonic-gate else 7237c478bd9Sstevel@tonic-gate close(fd); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate #else 7267c478bd9Sstevel@tonic-gate 727*ab25eeb5Syz for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 7287c478bd9Sstevel@tonic-gate ifp->if_output = write_output; 7297c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 7307c478bd9Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 7317c478bd9Sstevel@tonic-gate if (fd == -1) 7327c478bd9Sstevel@tonic-gate perror("open"); 7337c478bd9Sstevel@tonic-gate else 7347c478bd9Sstevel@tonic-gate close(fd); 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate #endif 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate int fr_fastroute(m, mpp, fin, fdp) 7417c478bd9Sstevel@tonic-gate mb_t *m, **mpp; 7427c478bd9Sstevel@tonic-gate fr_info_t *fin; 7437c478bd9Sstevel@tonic-gate frdest_t *fdp; 7447c478bd9Sstevel@tonic-gate { 7457c478bd9Sstevel@tonic-gate struct ifnet *ifp = fdp->fd_ifp; 7467c478bd9Sstevel@tonic-gate ip_t *ip = fin->fin_ip; 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate if (!ifp) 7497c478bd9Sstevel@tonic-gate return 0; /* no routing table out here */ 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate ip->ip_len = htons((u_short)ip->ip_len); 7527c478bd9Sstevel@tonic-gate ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 7537c478bd9Sstevel@tonic-gate ip->ip_sum = 0; 754*ab25eeb5Syz #if defined(__sgi) && (IRIX < 60500) 7557c478bd9Sstevel@tonic-gate (*ifp->if_output)(ifp, (void *)ip, NULL); 7567c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 7577c478bd9Sstevel@tonic-gate (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 7587c478bd9Sstevel@tonic-gate # else 7597c478bd9Sstevel@tonic-gate (*ifp->if_output)(ifp, (void *)m, NULL, 0); 7607c478bd9Sstevel@tonic-gate # endif 7617c478bd9Sstevel@tonic-gate #endif 7627c478bd9Sstevel@tonic-gate return 0; 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate int fr_send_reset(fin) 7677c478bd9Sstevel@tonic-gate fr_info_t *fin; 7687c478bd9Sstevel@tonic-gate { 7697c478bd9Sstevel@tonic-gate verbose("- TCP RST sent\n"); 7707c478bd9Sstevel@tonic-gate return 0; 7717c478bd9Sstevel@tonic-gate } 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate int fr_send_icmp_err(type, fin, dst) 7757c478bd9Sstevel@tonic-gate int type; 7767c478bd9Sstevel@tonic-gate fr_info_t *fin; 7777c478bd9Sstevel@tonic-gate int dst; 7787c478bd9Sstevel@tonic-gate { 779*ab25eeb5Syz verbose("- ICMP unreachable sent\n"); 7807c478bd9Sstevel@tonic-gate return 0; 7817c478bd9Sstevel@tonic-gate } 7827c478bd9Sstevel@tonic-gate 7837c478bd9Sstevel@tonic-gate 784*ab25eeb5Syz void frsync(ifp) 785*ab25eeb5Syz void *ifp; 7867c478bd9Sstevel@tonic-gate { 7877c478bd9Sstevel@tonic-gate return; 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate void m_freem(m) 7927c478bd9Sstevel@tonic-gate mb_t *m; 7937c478bd9Sstevel@tonic-gate { 7947c478bd9Sstevel@tonic-gate return; 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate void m_copydata(m, off, len, cp) 7997c478bd9Sstevel@tonic-gate mb_t *m; 8007c478bd9Sstevel@tonic-gate int off, len; 8017c478bd9Sstevel@tonic-gate caddr_t cp; 8027c478bd9Sstevel@tonic-gate { 8037c478bd9Sstevel@tonic-gate bcopy((char *)m + off, cp, len); 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate int ipfuiomove(buf, len, rwflag, uio) 8087c478bd9Sstevel@tonic-gate caddr_t buf; 8097c478bd9Sstevel@tonic-gate int len, rwflag; 8107c478bd9Sstevel@tonic-gate struct uio *uio; 8117c478bd9Sstevel@tonic-gate { 8127c478bd9Sstevel@tonic-gate int left, ioc, num, offset; 8137c478bd9Sstevel@tonic-gate struct iovec *io; 8147c478bd9Sstevel@tonic-gate char *start; 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate if (rwflag == UIO_READ) { 8177c478bd9Sstevel@tonic-gate left = len; 8187c478bd9Sstevel@tonic-gate ioc = 0; 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate offset = uio->uio_offset; 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate while ((left > 0) && (ioc < uio->uio_iovcnt)) { 8237c478bd9Sstevel@tonic-gate io = uio->uio_iov + ioc; 8247c478bd9Sstevel@tonic-gate num = io->iov_len; 8257c478bd9Sstevel@tonic-gate if (num > left) 8267c478bd9Sstevel@tonic-gate num = left; 8277c478bd9Sstevel@tonic-gate start = (char *)io->iov_base + offset; 8287c478bd9Sstevel@tonic-gate if (start > (char *)io->iov_base + io->iov_len) { 8297c478bd9Sstevel@tonic-gate offset -= io->iov_len; 8307c478bd9Sstevel@tonic-gate ioc++; 8317c478bd9Sstevel@tonic-gate continue; 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate bcopy(buf, start, num); 8347c478bd9Sstevel@tonic-gate uio->uio_resid -= num; 8357c478bd9Sstevel@tonic-gate uio->uio_offset += num; 8367c478bd9Sstevel@tonic-gate left -= num; 8377c478bd9Sstevel@tonic-gate if (left > 0) 8387c478bd9Sstevel@tonic-gate ioc++; 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate if (left > 0) 8417c478bd9Sstevel@tonic-gate return EFAULT; 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate return 0; 8447c478bd9Sstevel@tonic-gate } 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate u_32_t fr_newisn(fin) 8487c478bd9Sstevel@tonic-gate fr_info_t *fin; 8497c478bd9Sstevel@tonic-gate { 8507c478bd9Sstevel@tonic-gate static int iss_seq_off = 0; 8517c478bd9Sstevel@tonic-gate u_char hash[16]; 8527c478bd9Sstevel@tonic-gate u_32_t newiss; 8537c478bd9Sstevel@tonic-gate MD5_CTX ctx; 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate /* 8567c478bd9Sstevel@tonic-gate * Compute the base value of the ISS. It is a hash 8577c478bd9Sstevel@tonic-gate * of (saddr, sport, daddr, dport, secret). 8587c478bd9Sstevel@tonic-gate */ 8597c478bd9Sstevel@tonic-gate MD5Init(&ctx); 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 8627c478bd9Sstevel@tonic-gate sizeof(fin->fin_fi.fi_src)); 8637c478bd9Sstevel@tonic-gate MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 8647c478bd9Sstevel@tonic-gate sizeof(fin->fin_fi.fi_dst)); 8657c478bd9Sstevel@tonic-gate MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 8687c478bd9Sstevel@tonic-gate 8697c478bd9Sstevel@tonic-gate MD5Final(hash, &ctx); 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate memcpy(&newiss, hash, sizeof(newiss)); 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate /* 8747c478bd9Sstevel@tonic-gate * Now increment our "timer", and add it in to 8757c478bd9Sstevel@tonic-gate * the computed value. 8767c478bd9Sstevel@tonic-gate * 8777c478bd9Sstevel@tonic-gate * XXX Use `addin'? 8787c478bd9Sstevel@tonic-gate * XXX TCP_ISSINCR too large to use? 8797c478bd9Sstevel@tonic-gate */ 8807c478bd9Sstevel@tonic-gate iss_seq_off += 0x00010000; 8817c478bd9Sstevel@tonic-gate newiss += iss_seq_off; 8827c478bd9Sstevel@tonic-gate return newiss; 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 8877c478bd9Sstevel@tonic-gate /* Function: fr_nextipid */ 8887c478bd9Sstevel@tonic-gate /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 8897c478bd9Sstevel@tonic-gate /* Parameters: fin(I) - pointer to packet information */ 8907c478bd9Sstevel@tonic-gate /* */ 8917c478bd9Sstevel@tonic-gate /* Returns the next IPv4 ID to use for this packet. */ 8927c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 8937c478bd9Sstevel@tonic-gate INLINE u_short fr_nextipid(fin) 8947c478bd9Sstevel@tonic-gate fr_info_t *fin; 8957c478bd9Sstevel@tonic-gate { 8967c478bd9Sstevel@tonic-gate static u_short ipid = 0; 8977c478bd9Sstevel@tonic-gate u_short id; 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate MUTEX_ENTER(&ipf_rw); 9007c478bd9Sstevel@tonic-gate id = ipid++; 9017c478bd9Sstevel@tonic-gate MUTEX_EXIT(&ipf_rw); 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate return id; 9047c478bd9Sstevel@tonic-gate } 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate INLINE void fr_checkv4sum(fin) 9087c478bd9Sstevel@tonic-gate fr_info_t *fin; 9097c478bd9Sstevel@tonic-gate { 9107c478bd9Sstevel@tonic-gate if (fr_checkl4sum(fin) == -1) 9117c478bd9Sstevel@tonic-gate fin->fin_flx |= FI_BAD; 9127c478bd9Sstevel@tonic-gate } 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate #ifdef USE_INET6 9167c478bd9Sstevel@tonic-gate INLINE void fr_checkv6sum(fin) 9177c478bd9Sstevel@tonic-gate fr_info_t *fin; 9187c478bd9Sstevel@tonic-gate { 9197c478bd9Sstevel@tonic-gate if (fr_checkl4sum(fin) == -1) 9207c478bd9Sstevel@tonic-gate fin->fin_flx |= FI_BAD; 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate #endif 923*ab25eeb5Syz 924*ab25eeb5Syz 925*ab25eeb5Syz /* 926*ab25eeb5Syz * See above for description, except that all addressing is in user space. 927*ab25eeb5Syz */ 928*ab25eeb5Syz int copyoutptr(src, dst, size) 929*ab25eeb5Syz void *src, *dst; 930*ab25eeb5Syz size_t size; 931*ab25eeb5Syz { 932*ab25eeb5Syz caddr_t ca; 933*ab25eeb5Syz 934*ab25eeb5Syz bcopy(dst, (char *)&ca, sizeof(ca)); 935*ab25eeb5Syz bcopy(src, ca, size); 936*ab25eeb5Syz return 0; 937*ab25eeb5Syz } 938*ab25eeb5Syz 939*ab25eeb5Syz 940*ab25eeb5Syz /* 941*ab25eeb5Syz * See above for description, except that all addressing is in user space. 942*ab25eeb5Syz */ 943*ab25eeb5Syz int copyinptr(src, dst, size) 944*ab25eeb5Syz void *src, *dst; 945*ab25eeb5Syz size_t size; 946*ab25eeb5Syz { 947*ab25eeb5Syz caddr_t ca; 948*ab25eeb5Syz 949*ab25eeb5Syz bcopy(src, (char *)&ca, sizeof(ca)); 950*ab25eeb5Syz bcopy(ca, dst, size); 951*ab25eeb5Syz return 0; 952*ab25eeb5Syz } 953*ab25eeb5Syz 954*ab25eeb5Syz 955*ab25eeb5Syz /* 956*ab25eeb5Syz * return the first IP Address associated with an interface 957*ab25eeb5Syz */ 958*ab25eeb5Syz int fr_ifpaddr(v, atype, ifptr, inp, inpmask) 959*ab25eeb5Syz int v, atype; 960*ab25eeb5Syz void *ifptr; 961*ab25eeb5Syz struct in_addr *inp, *inpmask; 962*ab25eeb5Syz { 963*ab25eeb5Syz struct ifnet *ifp = ifptr; 964*ab25eeb5Syz #ifdef __sgi 965*ab25eeb5Syz struct in_ifaddr *ifa; 966*ab25eeb5Syz #else 967*ab25eeb5Syz struct ifaddr *ifa; 968*ab25eeb5Syz #endif 969*ab25eeb5Syz 970*ab25eeb5Syz #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 971*ab25eeb5Syz ifa = ifp->if_addrlist.tqh_first; 972*ab25eeb5Syz #else 973*ab25eeb5Syz # ifdef __sgi 974*ab25eeb5Syz ifa = (struct in_ifaddr *)ifp->in_ifaddr; 975*ab25eeb5Syz # else 976*ab25eeb5Syz ifa = ifp->if_addrlist; 977*ab25eeb5Syz # endif 978*ab25eeb5Syz #endif 979*ab25eeb5Syz if (ifa != NULL) { 980*ab25eeb5Syz struct sockaddr_in *sin, mask; 981*ab25eeb5Syz 982*ab25eeb5Syz mask.sin_addr.s_addr = 0xffffffff; 983*ab25eeb5Syz 984*ab25eeb5Syz #ifdef __sgi 985*ab25eeb5Syz sin = (struct sockaddr_in *)&ifa->ia_addr; 986*ab25eeb5Syz #else 987*ab25eeb5Syz sin = (struct sockaddr_in *)&ifa->ifa_addr; 988*ab25eeb5Syz #endif 989*ab25eeb5Syz 990*ab25eeb5Syz return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask); 991*ab25eeb5Syz } 992*ab25eeb5Syz return 0; 993*ab25eeb5Syz } 994