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