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 * 633f2fefdSDarren Reed * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 77c478bd9Sstevel@tonic-gate * Use is subject to license terms. 87c478bd9Sstevel@tonic-gate */ 97c478bd9Sstevel@tonic-gate 10*e0f1facfSToomas Soome #ifdef SOLARIS 11*e0f1facfSToomas Soome #undef SOLARIS 12*e0f1facfSToomas Soome #endif 13*e0f1facfSToomas Soome #if (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 14*e0f1facfSToomas Soome #define SOLARIS (1) 15*e0f1facfSToomas Soome #else 16*e0f1facfSToomas Soome #define SOLARIS (0) 177c478bd9Sstevel@tonic-gate #endif 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate #include <sys/param.h> 207c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__) && !defined(__FreeBSD_version) 217c478bd9Sstevel@tonic-gate # if defined(IPFILTER_LKM) 227c478bd9Sstevel@tonic-gate # ifndef __FreeBSD_cc_version 237c478bd9Sstevel@tonic-gate # include <osreldate.h> 247c478bd9Sstevel@tonic-gate # else 257c478bd9Sstevel@tonic-gate # if __FreeBSD_cc_version < 430000 267c478bd9Sstevel@tonic-gate # include <osreldate.h> 277c478bd9Sstevel@tonic-gate # endif 287c478bd9Sstevel@tonic-gate # endif 297c478bd9Sstevel@tonic-gate # endif 307c478bd9Sstevel@tonic-gate #endif 317c478bd9Sstevel@tonic-gate #include <sys/errno.h> 32ab25eeb5Syz155240 #if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) 33ab25eeb5Syz155240 # include <sys/kern_svcs.h> 34ab25eeb5Syz155240 #endif 357c478bd9Sstevel@tonic-gate #include <sys/types.h> 367c478bd9Sstevel@tonic-gate #define _KERNEL 37ab25eeb5Syz155240 #define KERNEL 387c478bd9Sstevel@tonic-gate #ifdef __OpenBSD__ 397c478bd9Sstevel@tonic-gate struct file; 407c478bd9Sstevel@tonic-gate #endif 417c478bd9Sstevel@tonic-gate #include <sys/uio.h> 427c478bd9Sstevel@tonic-gate #undef _KERNEL 43ab25eeb5Syz155240 #undef KERNEL 447c478bd9Sstevel@tonic-gate #include <sys/file.h> 457c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 467c478bd9Sstevel@tonic-gate #ifdef __sgi 477c478bd9Sstevel@tonic-gate # include <sys/ptimers.h> 487c478bd9Sstevel@tonic-gate #endif 497c478bd9Sstevel@tonic-gate #include <sys/time.h> 50f56257d8SToomas Soome #if !defined(SOLARIS) 517c478bd9Sstevel@tonic-gate # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) 527c478bd9Sstevel@tonic-gate # include <sys/dirent.h> 537c478bd9Sstevel@tonic-gate # else 547c478bd9Sstevel@tonic-gate # include <sys/dir.h> 557c478bd9Sstevel@tonic-gate # endif 567c478bd9Sstevel@tonic-gate #else 577c478bd9Sstevel@tonic-gate # include <sys/filio.h> 587c478bd9Sstevel@tonic-gate #endif 59ab25eeb5Syz155240 #ifndef linux 607c478bd9Sstevel@tonic-gate # include <sys/protosw.h> 61ab25eeb5Syz155240 #endif 627c478bd9Sstevel@tonic-gate #include <sys/socket.h> 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate #include <stdio.h> 657c478bd9Sstevel@tonic-gate #include <string.h> 667c478bd9Sstevel@tonic-gate #include <stdlib.h> 677c478bd9Sstevel@tonic-gate #include <ctype.h> 687c478bd9Sstevel@tonic-gate #include <fcntl.h> 69f4b3ec61Sdh155122 #include <sys/zone.h> 70ab25eeb5Syz155240 #include <arpa/inet.h> 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate #ifdef __hpux 737c478bd9Sstevel@tonic-gate # define _NET_ROUTE_INCLUDED 747c478bd9Sstevel@tonic-gate #endif 757c478bd9Sstevel@tonic-gate #include <net/if.h> 767c478bd9Sstevel@tonic-gate #ifdef sun 777c478bd9Sstevel@tonic-gate # include <net/af.h> 787c478bd9Sstevel@tonic-gate #endif 797c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000 807c478bd9Sstevel@tonic-gate # include <net/if_var.h> 817c478bd9Sstevel@tonic-gate #endif 827c478bd9Sstevel@tonic-gate #ifdef __sgi 837c478bd9Sstevel@tonic-gate #include <sys/debug.h> 847c478bd9Sstevel@tonic-gate # ifdef IFF_DRVRLOCK /* IRIX6 */ 857c478bd9Sstevel@tonic-gate #include <sys/hashing.h> 867c478bd9Sstevel@tonic-gate # endif 877c478bd9Sstevel@tonic-gate #endif 88ab25eeb5Syz155240 #if defined(__FreeBSD__) 89ab25eeb5Syz155240 # include "radix_ipf.h" 90ab25eeb5Syz155240 #endif 917c478bd9Sstevel@tonic-gate #include <net/route.h> 927c478bd9Sstevel@tonic-gate #include <netinet/in.h> 937c478bd9Sstevel@tonic-gate #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \ 94ab25eeb5Syz155240 !defined(__hpux) && !defined(linux) 957c478bd9Sstevel@tonic-gate # include <netinet/in_var.h> 967c478bd9Sstevel@tonic-gate #endif 977c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 987c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 99ab25eeb5Syz155240 #if !defined(linux) 1007c478bd9Sstevel@tonic-gate # include <netinet/ip_var.h> 101ab25eeb5Syz155240 #endif 1027c478bd9Sstevel@tonic-gate #include <netinet/tcp.h> 1037c478bd9Sstevel@tonic-gate #if defined(__osf__) 1047c478bd9Sstevel@tonic-gate # include <netinet/tcp_timer.h> 1057c478bd9Sstevel@tonic-gate #endif 106ab25eeb5Syz155240 #if defined(__osf__) || defined(__hpux) || defined(__sgi) 107ab25eeb5Syz155240 # include "radix_ipf_local.h" 108ab25eeb5Syz155240 # define _RADIX_H_ 109ab25eeb5Syz155240 #endif 1107c478bd9Sstevel@tonic-gate #include <netinet/udp.h> 1117c478bd9Sstevel@tonic-gate #include <netinet/tcpip.h> 1127c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h> 1137c478bd9Sstevel@tonic-gate #include <unistd.h> 1147c478bd9Sstevel@tonic-gate #include <syslog.h> 1157c478bd9Sstevel@tonic-gate #ifdef __hpux 1167c478bd9Sstevel@tonic-gate # undef _NET_ROUTE_INCLUDED 1177c478bd9Sstevel@tonic-gate #endif 1187c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h" 1197c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h" 1207c478bd9Sstevel@tonic-gate #include "netinet/ip_nat.h" 1217c478bd9Sstevel@tonic-gate #include "netinet/ip_frag.h" 1227c478bd9Sstevel@tonic-gate #include "netinet/ip_state.h" 1237c478bd9Sstevel@tonic-gate #include "netinet/ip_proxy.h" 1247c478bd9Sstevel@tonic-gate #include "netinet/ip_auth.h" 1257c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SYNC 1267c478bd9Sstevel@tonic-gate #include "netinet/ip_sync.h" 1277c478bd9Sstevel@tonic-gate #endif 1287c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SCAN 1297c478bd9Sstevel@tonic-gate #include "netinet/ip_scan.h" 1307c478bd9Sstevel@tonic-gate #endif 1317c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h" 1327c478bd9Sstevel@tonic-gate #ifdef IPFILTER_COMPILED 1337c478bd9Sstevel@tonic-gate # include "netinet/ip_rules.h" 1347c478bd9Sstevel@tonic-gate #endif 135f4b3ec61Sdh155122 #include "netinet/ipf_stack.h" 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 142ab25eeb5Syz155240 #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 153f4b3ec61Sdh155122 static int frzerostats __P((caddr_t, ipf_stack_t *ifs)); 154ab25eeb5Syz155240 static void fr_setifpaddr __P((struct ifnet *, char *)); 1557c478bd9Sstevel@tonic-gate void init_ifp __P((void)); 156ab25eeb5Syz155240 #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 1767ddc9b1aSDarren Reed int iplattach(ifs) 177f4b3ec61Sdh155122 ipf_stack_t *ifs; 1787c478bd9Sstevel@tonic-gate { 179f4b3ec61Sdh155122 ifs->ifs_fr_running = 1; 1807c478bd9Sstevel@tonic-gate return 0; 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate 184f4b3ec61Sdh155122 int ipldetach(ifs) 185f4b3ec61Sdh155122 ipf_stack_t *ifs; 1867c478bd9Sstevel@tonic-gate { 187f4b3ec61Sdh155122 ifs->ifs_fr_running = -1; 1887c478bd9Sstevel@tonic-gate return 0; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate 192f4b3ec61Sdh155122 static int frzerostats(data, ifs) 1937c478bd9Sstevel@tonic-gate caddr_t data; 194f4b3ec61Sdh155122 ipf_stack_t *ifs; 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate friostat_t fio; 1977c478bd9Sstevel@tonic-gate int error; 1987c478bd9Sstevel@tonic-gate 199f4b3ec61Sdh155122 fr_getstat(&fio, ifs); 2007c478bd9Sstevel@tonic-gate error = copyoutptr(&fio, data, sizeof(fio)); 2017c478bd9Sstevel@tonic-gate if (error) 2027c478bd9Sstevel@tonic-gate return EFAULT; 2037c478bd9Sstevel@tonic-gate 204f4b3ec61Sdh155122 bzero((char *)ifs->ifs_frstats, sizeof(*ifs->ifs_frstats) * 2); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate return 0; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* 2117c478bd9Sstevel@tonic-gate * Filter ioctl interface. 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate int iplioctl(dev, cmd, data, mode) 2147c478bd9Sstevel@tonic-gate int dev; 215ab25eeb5Syz155240 ioctlcmd_t cmd; 2167c478bd9Sstevel@tonic-gate caddr_t data; 2177c478bd9Sstevel@tonic-gate int mode; 2187c478bd9Sstevel@tonic-gate { 219f4b3ec61Sdh155122 int error = 0, unit = 0, tmp, uid; 2207c478bd9Sstevel@tonic-gate friostat_t fio; 221f4b3ec61Sdh155122 ipf_stack_t *ifs; 222f4b3ec61Sdh155122 extern ipf_stack_t *get_ifs(); 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate unit = dev; 225f4b3ec61Sdh155122 uid = getuid(); 226f4b3ec61Sdh155122 227f4b3ec61Sdh155122 ifs = get_ifs(); 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate SPL_NET(s); 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate if (unit == IPL_LOGNAT) { 232f4b3ec61Sdh155122 if (ifs->ifs_fr_running > 0) 233f4b3ec61Sdh155122 error = fr_nat_ioctl(data, cmd, mode, uid, NULL, ifs); 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_LOGSTATE) { 240f4b3ec61Sdh155122 if (ifs->ifs_fr_running > 0) 241f4b3ec61Sdh155122 error = fr_state_ioctl(data, cmd, mode, uid, NULL, ifs); 2427c478bd9Sstevel@tonic-gate else 2437c478bd9Sstevel@tonic-gate error = EIO; 2447c478bd9Sstevel@tonic-gate SPL_X(s); 2457c478bd9Sstevel@tonic-gate return error; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate if (unit == IPL_LOGAUTH) { 248f4b3ec61Sdh155122 if (ifs->ifs_fr_running > 0) { 249ab25eeb5Syz155240 if ((cmd == (ioctlcmd_t)SIOCADAFR) || 250ab25eeb5Syz155240 (cmd == (ioctlcmd_t)SIOCRMAFR)) { 2517c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) { 2527c478bd9Sstevel@tonic-gate error = EPERM; 2537c478bd9Sstevel@tonic-gate } else { 2547c478bd9Sstevel@tonic-gate error = frrequest(unit, cmd, data, 255f4b3ec61Sdh155122 ifs->ifs_fr_active, 1, ifs); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate } else { 25833f2fefdSDarren Reed error = fr_auth_ioctl(data, cmd, mode, uid, 25933f2fefdSDarren Reed NULL, ifs); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate } else 2627c478bd9Sstevel@tonic-gate error = EIO; 2637c478bd9Sstevel@tonic-gate SPL_X(s); 2647c478bd9Sstevel@tonic-gate return error; 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate if (unit == IPL_LOGSYNC) { 2677c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SYNC 268f4b3ec61Sdh155122 if (ifs->ifs_fr_running > 0) 2697c478bd9Sstevel@tonic-gate error = fr_sync_ioctl(data, cmd, mode); 2707c478bd9Sstevel@tonic-gate else 2717c478bd9Sstevel@tonic-gate #endif 2727c478bd9Sstevel@tonic-gate error = EIO; 2737c478bd9Sstevel@tonic-gate SPL_X(s); 2747c478bd9Sstevel@tonic-gate return error; 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate if (unit == IPL_LOGSCAN) { 2777c478bd9Sstevel@tonic-gate #ifdef IPFILTER_SCAN 278f4b3ec61Sdh155122 if (ifs->ifs_fr_running > 0) 2797c478bd9Sstevel@tonic-gate error = fr_scan_ioctl(data, cmd, mode); 2807c478bd9Sstevel@tonic-gate else 2817c478bd9Sstevel@tonic-gate #endif 2827c478bd9Sstevel@tonic-gate error = EIO; 2837c478bd9Sstevel@tonic-gate SPL_X(s); 2847c478bd9Sstevel@tonic-gate return error; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate if (unit == IPL_LOGLOOKUP) { 287f4b3ec61Sdh155122 if (ifs->ifs_fr_running > 0) 288f4b3ec61Sdh155122 error = ip_lookup_ioctl(data, cmd, mode, uid, 289f4b3ec61Sdh155122 NULL, ifs); 2907c478bd9Sstevel@tonic-gate else 2917c478bd9Sstevel@tonic-gate error = EIO; 2927c478bd9Sstevel@tonic-gate SPL_X(s); 2937c478bd9Sstevel@tonic-gate return error; 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate switch (cmd) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate case FIONREAD : 2997c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOG 300f4b3ec61Sdh155122 error = COPYOUT(&ifs->ifs_iplused[IPL_LOGIPF], (caddr_t)data, 301f4b3ec61Sdh155122 sizeof(ifs->ifs_iplused[IPL_LOGIPF])); 3027c478bd9Sstevel@tonic-gate #endif 3037c478bd9Sstevel@tonic-gate break; 3047c478bd9Sstevel@tonic-gate case SIOCFRENB : 3057c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3067c478bd9Sstevel@tonic-gate error = EPERM; 3077c478bd9Sstevel@tonic-gate else { 3087c478bd9Sstevel@tonic-gate error = COPYIN(data, &tmp, sizeof(tmp)); 3097c478bd9Sstevel@tonic-gate if (error) 3107c478bd9Sstevel@tonic-gate break; 3117c478bd9Sstevel@tonic-gate if (tmp) 3127ddc9b1aSDarren Reed error = iplattach(ifs); 3137c478bd9Sstevel@tonic-gate else 314f4b3ec61Sdh155122 error = ipldetach(ifs); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate break; 317ab25eeb5Syz155240 case SIOCIPFSET : 318ab25eeb5Syz155240 if (!(mode & FWRITE)) { 319ab25eeb5Syz155240 error = EPERM; 320ab25eeb5Syz155240 break; 321ab25eeb5Syz155240 } 322f56257d8SToomas Soome /* FALLTHROUGH */ 323ab25eeb5Syz155240 case SIOCIPFGETNEXT : 324ab25eeb5Syz155240 case SIOCIPFGET : 325f4b3ec61Sdh155122 error = fr_ipftune(cmd, (void *)data, ifs); 326ab25eeb5Syz155240 break; 3277c478bd9Sstevel@tonic-gate case SIOCSETFF : 3287c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3297c478bd9Sstevel@tonic-gate error = EPERM; 3307c478bd9Sstevel@tonic-gate else 331f4b3ec61Sdh155122 error = COPYIN(data, &ifs->ifs_fr_flags, 332f4b3ec61Sdh155122 sizeof(ifs->ifs_fr_flags)); 3337c478bd9Sstevel@tonic-gate break; 3347c478bd9Sstevel@tonic-gate case SIOCGETFF : 335f4b3ec61Sdh155122 error = COPYOUT(&ifs->ifs_fr_flags, data, 336f4b3ec61Sdh155122 sizeof(ifs->ifs_fr_flags)); 3377c478bd9Sstevel@tonic-gate break; 3387c478bd9Sstevel@tonic-gate case SIOCFUNCL : 3397c478bd9Sstevel@tonic-gate error = fr_resolvefunc(data); 3407c478bd9Sstevel@tonic-gate break; 3417c478bd9Sstevel@tonic-gate case SIOCINAFR : 3427c478bd9Sstevel@tonic-gate case SIOCRMAFR : 3437c478bd9Sstevel@tonic-gate case SIOCADAFR : 3447c478bd9Sstevel@tonic-gate case SIOCZRLST : 3457c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3467c478bd9Sstevel@tonic-gate error = EPERM; 3477c478bd9Sstevel@tonic-gate else 348f4b3ec61Sdh155122 error = frrequest(unit, cmd, data, 349f4b3ec61Sdh155122 ifs->ifs_fr_active, 1, ifs); 3507c478bd9Sstevel@tonic-gate break; 3517c478bd9Sstevel@tonic-gate case SIOCINIFR : 3527c478bd9Sstevel@tonic-gate case SIOCRMIFR : 3537c478bd9Sstevel@tonic-gate case SIOCADIFR : 3547c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3557c478bd9Sstevel@tonic-gate error = EPERM; 3567c478bd9Sstevel@tonic-gate else 357f4b3ec61Sdh155122 error = frrequest(unit, cmd, data, 358f4b3ec61Sdh155122 1 - ifs->ifs_fr_active, 1, ifs); 3597c478bd9Sstevel@tonic-gate break; 3607c478bd9Sstevel@tonic-gate case SIOCSWAPA : 3617c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3627c478bd9Sstevel@tonic-gate error = EPERM; 3637c478bd9Sstevel@tonic-gate else { 364f4b3ec61Sdh155122 *(u_int *)data = ifs->ifs_fr_active; 365f4b3ec61Sdh155122 ifs->ifs_fr_active = 1 - ifs->ifs_fr_active; 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate break; 3687c478bd9Sstevel@tonic-gate case SIOCGETFS : 369f4b3ec61Sdh155122 fr_getstat(&fio, ifs); 3707c478bd9Sstevel@tonic-gate error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); 3717c478bd9Sstevel@tonic-gate break; 3727c478bd9Sstevel@tonic-gate case SIOCFRZST : 3737c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3747c478bd9Sstevel@tonic-gate error = EPERM; 3757c478bd9Sstevel@tonic-gate else 376f4b3ec61Sdh155122 error = frzerostats(data, ifs); 3777c478bd9Sstevel@tonic-gate break; 3787c478bd9Sstevel@tonic-gate case SIOCIPFFL : 3797c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 3807c478bd9Sstevel@tonic-gate error = EPERM; 3817c478bd9Sstevel@tonic-gate else { 3827c478bd9Sstevel@tonic-gate error = COPYIN(data, &tmp, sizeof(tmp)); 3837c478bd9Sstevel@tonic-gate if (!error) { 384f4b3ec61Sdh155122 tmp = frflush(unit, 4, tmp, ifs); 3857c478bd9Sstevel@tonic-gate error = COPYOUT(&tmp, data, sizeof(tmp)); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate break; 3897663b816Sml37995 #ifdef USE_INET6 3907663b816Sml37995 case SIOCIPFL6 : 3917663b816Sml37995 if (!(mode & FWRITE)) 3927663b816Sml37995 error = EPERM; 3937663b816Sml37995 else { 3947663b816Sml37995 error = COPYIN(data, &tmp, sizeof(tmp)); 3957663b816Sml37995 if (!error) { 396f4b3ec61Sdh155122 tmp = frflush(unit, 6, tmp, ifs); 3977663b816Sml37995 error = COPYOUT(&tmp, data, sizeof(tmp)); 3987663b816Sml37995 } 3997663b816Sml37995 } 4007663b816Sml37995 break; 4017663b816Sml37995 #endif 4027c478bd9Sstevel@tonic-gate case SIOCSTLCK : 4037c478bd9Sstevel@tonic-gate error = COPYIN(data, &tmp, sizeof(tmp)); 4047c478bd9Sstevel@tonic-gate if (error == 0) { 405f4b3ec61Sdh155122 ifs->ifs_fr_state_lock = tmp; 406f4b3ec61Sdh155122 ifs->ifs_fr_nat_lock = tmp; 407f4b3ec61Sdh155122 ifs->ifs_fr_frag_lock = tmp; 408f4b3ec61Sdh155122 ifs->ifs_fr_auth_lock = tmp; 4097c478bd9Sstevel@tonic-gate } else 4107c478bd9Sstevel@tonic-gate error = EFAULT; 4117c478bd9Sstevel@tonic-gate break; 4127c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOG 4137c478bd9Sstevel@tonic-gate case SIOCIPFFB : 4147c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 4157c478bd9Sstevel@tonic-gate error = EPERM; 4167c478bd9Sstevel@tonic-gate else 417f4b3ec61Sdh155122 *(int *)data = ipflog_clear(unit, ifs); 4187c478bd9Sstevel@tonic-gate break; 4197c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOG */ 4207c478bd9Sstevel@tonic-gate case SIOCGFRST : 421f4b3ec61Sdh155122 error = fr_outobj(data, fr_fragstats(ifs), IPFOBJ_FRAGSTAT); 4227c478bd9Sstevel@tonic-gate break; 4237c478bd9Sstevel@tonic-gate case SIOCFRSYN : 4247c478bd9Sstevel@tonic-gate if (!(mode & FWRITE)) 4257c478bd9Sstevel@tonic-gate error = EPERM; 4267c478bd9Sstevel@tonic-gate else { 427f4b3ec61Sdh155122 frsync(IPFSYNC_RESYNC, IPFSYNC_RESYNC, NULL, NULL, ifs); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate break; 4307c478bd9Sstevel@tonic-gate default : 4317c478bd9Sstevel@tonic-gate error = EINVAL; 4327c478bd9Sstevel@tonic-gate break; 4337c478bd9Sstevel@tonic-gate } 4347c478bd9Sstevel@tonic-gate SPL_X(s); 4357c478bd9Sstevel@tonic-gate return error; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate 439f4b3ec61Sdh155122 void fr_forgetifp(ifp, ifs) 4407c478bd9Sstevel@tonic-gate void *ifp; 441f4b3ec61Sdh155122 ipf_stack_t *ifs; 4427c478bd9Sstevel@tonic-gate { 4437c478bd9Sstevel@tonic-gate register frentry_t *f; 4447c478bd9Sstevel@tonic-gate 445f4b3ec61Sdh155122 WRITE_ENTER(&ifs->ifs_ipf_mutex); 446f4b3ec61Sdh155122 for (f = ifs->ifs_ipacct[0][ifs->ifs_fr_active]; (f != NULL); 447f4b3ec61Sdh155122 f = f->fr_next) 4487c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4497c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 450f4b3ec61Sdh155122 for (f = ifs->ifs_ipacct[1][ifs->ifs_fr_active]; (f != NULL); 451f4b3ec61Sdh155122 f = f->fr_next) 4527c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4537c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 454f4b3ec61Sdh155122 for (f = ifs->ifs_ipfilter[0][ifs->ifs_fr_active]; (f != NULL); 455f4b3ec61Sdh155122 f = f->fr_next) 4567c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4577c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 458f4b3ec61Sdh155122 for (f = ifs->ifs_ipfilter[1][ifs->ifs_fr_active]; (f != NULL); 459f4b3ec61Sdh155122 f = f->fr_next) 4607c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4617c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4627c478bd9Sstevel@tonic-gate #ifdef USE_INET6 463f4b3ec61Sdh155122 for (f = ifs->ifs_ipacct6[0][ifs->ifs_fr_active]; (f != NULL); 464f4b3ec61Sdh155122 f = f->fr_next) 4657c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4667c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 467f4b3ec61Sdh155122 for (f = ifs->ifs_ipacct6[1][ifs->ifs_fr_active]; (f != NULL); 468f4b3ec61Sdh155122 f = f->fr_next) 4697c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4707c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 471f4b3ec61Sdh155122 for (f = ifs->ifs_ipfilter6[0][ifs->ifs_fr_active]; (f != NULL); 472f4b3ec61Sdh155122 f = f->fr_next) 4737c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4747c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 475f4b3ec61Sdh155122 for (f = ifs->ifs_ipfilter6[1][ifs->ifs_fr_active]; (f != NULL); 476f4b3ec61Sdh155122 f = f->fr_next) 4777c478bd9Sstevel@tonic-gate if (f->fr_ifa == ifp) 4787c478bd9Sstevel@tonic-gate f->fr_ifa = (void *)-1; 4797c478bd9Sstevel@tonic-gate #endif 480f4b3ec61Sdh155122 RWLOCK_EXIT(&ifs->ifs_ipf_mutex); 481d6c23f6fSyx160601 fr_natifpsync(IPFSYNC_OLDIFP, 4, ifp, NULL, ifs); 482d6c23f6fSyx160601 fr_natifpsync(IPFSYNC_OLDIFP, 6, ifp, NULL, ifs); 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate 486f4b3ec61Sdh155122 void fr_resolvedest(fdp, v, ifs) 4877c478bd9Sstevel@tonic-gate frdest_t *fdp; 4887c478bd9Sstevel@tonic-gate int v; 489f4b3ec61Sdh155122 ipf_stack_t *ifs; 4907c478bd9Sstevel@tonic-gate { 4917c478bd9Sstevel@tonic-gate fdp->fd_ifp = NULL; 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate if (*fdp->fd_ifname) { 494f4b3ec61Sdh155122 fdp->fd_ifp = GETIFP(fdp->fd_ifname, v, ifs); 4957c478bd9Sstevel@tonic-gate if (!fdp->fd_ifp) 4967c478bd9Sstevel@tonic-gate fdp->fd_ifp = (struct ifnet *)-1; 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate 501ab25eeb5Syz155240 #if defined(__sgi) && (IRIX < 60500) 5027c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s) 5037c478bd9Sstevel@tonic-gate #else 5047c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 5057c478bd9Sstevel@tonic-gate static int no_output (ifp, m, s, rt, cp) 5067c478bd9Sstevel@tonic-gate char *cp; 5077c478bd9Sstevel@tonic-gate # else 5087c478bd9Sstevel@tonic-gate static int no_output(ifp, m, s, rt) 5097c478bd9Sstevel@tonic-gate # endif 5107c478bd9Sstevel@tonic-gate struct rtentry *rt; 5117c478bd9Sstevel@tonic-gate #endif 5127c478bd9Sstevel@tonic-gate struct ifnet *ifp; 5137c478bd9Sstevel@tonic-gate struct mbuf *m; 5147c478bd9Sstevel@tonic-gate struct sockaddr *s; 5157c478bd9Sstevel@tonic-gate { 5167c478bd9Sstevel@tonic-gate return 0; 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate 520ab25eeb5Syz155240 #if defined(__sgi) && (IRIX < 60500) 5217c478bd9Sstevel@tonic-gate static int write_output(ifp, m, s) 5227c478bd9Sstevel@tonic-gate #else 5237c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 5247c478bd9Sstevel@tonic-gate static int write_output (ifp, m, s, rt, cp) 5257c478bd9Sstevel@tonic-gate char *cp; 5267c478bd9Sstevel@tonic-gate # else 5277c478bd9Sstevel@tonic-gate static int write_output(ifp, m, s, rt) 5287c478bd9Sstevel@tonic-gate # endif 5297c478bd9Sstevel@tonic-gate struct rtentry *rt; 5307c478bd9Sstevel@tonic-gate #endif 5317c478bd9Sstevel@tonic-gate struct ifnet *ifp; 5327c478bd9Sstevel@tonic-gate struct mbuf *m; 5337c478bd9Sstevel@tonic-gate struct sockaddr *s; 5347c478bd9Sstevel@tonic-gate { 5357c478bd9Sstevel@tonic-gate char fname[32]; 5367c478bd9Sstevel@tonic-gate mb_t *mb; 5377c478bd9Sstevel@tonic-gate ip_t *ip; 5387c478bd9Sstevel@tonic-gate int fd; 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate mb = (mb_t *)m; 5417c478bd9Sstevel@tonic-gate ip = MTOD(mb, ip_t *); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 544ab25eeb5Syz155240 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 545ab25eeb5Syz155240 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 5467c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s", ifp->if_xname); 5477c478bd9Sstevel@tonic-gate #else 5487c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 5497c478bd9Sstevel@tonic-gate #endif 5507c478bd9Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_APPEND); 5517c478bd9Sstevel@tonic-gate if (fd == -1) { 5527c478bd9Sstevel@tonic-gate perror("open"); 5537c478bd9Sstevel@tonic-gate return -1; 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate write(fd, (char *)ip, ntohs(ip->ip_len)); 5567c478bd9Sstevel@tonic-gate close(fd); 5577c478bd9Sstevel@tonic-gate return 0; 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate 561ab25eeb5Syz155240 static void fr_setifpaddr(ifp, addr) 562ab25eeb5Syz155240 struct ifnet *ifp; 563ab25eeb5Syz155240 char *addr; 564ab25eeb5Syz155240 { 565ab25eeb5Syz155240 #ifdef __sgi 566ab25eeb5Syz155240 struct in_ifaddr *ifa; 567ab25eeb5Syz155240 #else 568ab25eeb5Syz155240 struct ifaddr *ifa; 569ab25eeb5Syz155240 #endif 570ab25eeb5Syz155240 571ab25eeb5Syz155240 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 572ab25eeb5Syz155240 if (ifp->if_addrlist.tqh_first != NULL) 573ab25eeb5Syz155240 #else 574ab25eeb5Syz155240 # ifdef __sgi 575ab25eeb5Syz155240 if (ifp->in_ifaddr != NULL) 576ab25eeb5Syz155240 # else 577ab25eeb5Syz155240 if (ifp->if_addrlist != NULL) 578ab25eeb5Syz155240 # endif 579ab25eeb5Syz155240 #endif 580ab25eeb5Syz155240 return; 581ab25eeb5Syz155240 582ab25eeb5Syz155240 ifa = (struct ifaddr *)malloc(sizeof(*ifa)); 583ab25eeb5Syz155240 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 584ab25eeb5Syz155240 ifp->if_addrlist.tqh_first = ifa; 585ab25eeb5Syz155240 #else 586ab25eeb5Syz155240 # ifdef __sgi 587ab25eeb5Syz155240 ifp->in_ifaddr = ifa; 588ab25eeb5Syz155240 # else 589ab25eeb5Syz155240 ifp->if_addrlist = ifa; 590ab25eeb5Syz155240 # endif 591ab25eeb5Syz155240 #endif 592ab25eeb5Syz155240 593ab25eeb5Syz155240 if (ifa != NULL) { 594ab25eeb5Syz155240 struct sockaddr_in *sin; 595ab25eeb5Syz155240 596ab25eeb5Syz155240 #ifdef __sgi 597ab25eeb5Syz155240 sin = (struct sockaddr_in *)&ifa->ia_addr; 598ab25eeb5Syz155240 #else 599ab25eeb5Syz155240 sin = (struct sockaddr_in *)&ifa->ifa_addr; 600ab25eeb5Syz155240 #endif 601ab25eeb5Syz155240 sin->sin_addr.s_addr = inet_addr(addr); 602ab25eeb5Syz155240 if (sin->sin_addr.s_addr == 0) 603ab25eeb5Syz155240 abort(); 604ab25eeb5Syz155240 } 605ab25eeb5Syz155240 } 606ab25eeb5Syz155240 607f4b3ec61Sdh155122 /*ARGSUSED*/ 608f4b3ec61Sdh155122 struct ifnet *get_unit(name, v, ifs) 6097c478bd9Sstevel@tonic-gate char *name; 6107c478bd9Sstevel@tonic-gate int v; 611f4b3ec61Sdh155122 ipf_stack_t *ifs; 6127c478bd9Sstevel@tonic-gate { 613ab25eeb5Syz155240 struct ifnet *ifp, **ifpp, **old_ifneta; 614ab25eeb5Syz155240 char *addr; 6157c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 616ab25eeb5Syz155240 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 617ab25eeb5Syz155240 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate if (name == NULL) 6207c478bd9Sstevel@tonic-gate name = "anon0"; 6217c478bd9Sstevel@tonic-gate 622ab25eeb5Syz155240 addr = strchr(name, '='); 623ab25eeb5Syz155240 if (addr != NULL) 624ab25eeb5Syz155240 *addr++ = '\0'; 625ab25eeb5Syz155240 626ab25eeb5Syz155240 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 627ab25eeb5Syz155240 if (!strcmp(name, ifp->if_xname)) { 628ab25eeb5Syz155240 if (addr != NULL) 629ab25eeb5Syz155240 fr_setifpaddr(ifp, addr); 6307c478bd9Sstevel@tonic-gate return ifp; 6317c478bd9Sstevel@tonic-gate } 632ab25eeb5Syz155240 } 6337c478bd9Sstevel@tonic-gate #else 6347c478bd9Sstevel@tonic-gate char *s, ifname[LIFNAMSIZ+1]; 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate if (name == NULL) 6377c478bd9Sstevel@tonic-gate name = "anon0"; 6387c478bd9Sstevel@tonic-gate 639ab25eeb5Syz155240 addr = strchr(name, '='); 640ab25eeb5Syz155240 if (addr != NULL) 641ab25eeb5Syz155240 *addr++ = '\0'; 642ab25eeb5Syz155240 643ab25eeb5Syz155240 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 644381a2a9aSdr146992 COPYIFNAME(ifp, ifname, 0); 645ab25eeb5Syz155240 if (!strcmp(name, ifname)) { 646ab25eeb5Syz155240 if (addr != NULL) 647ab25eeb5Syz155240 fr_setifpaddr(ifp, addr); 6487c478bd9Sstevel@tonic-gate return ifp; 6497c478bd9Sstevel@tonic-gate } 650ab25eeb5Syz155240 } 6517c478bd9Sstevel@tonic-gate #endif 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate if (!ifneta) { 6547c478bd9Sstevel@tonic-gate ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 6557c478bd9Sstevel@tonic-gate if (!ifneta) 6567c478bd9Sstevel@tonic-gate return NULL; 6577c478bd9Sstevel@tonic-gate ifneta[1] = NULL; 6587c478bd9Sstevel@tonic-gate ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 6597c478bd9Sstevel@tonic-gate if (!ifneta[0]) { 6607c478bd9Sstevel@tonic-gate free(ifneta); 6617c478bd9Sstevel@tonic-gate return NULL; 6627c478bd9Sstevel@tonic-gate } 6637c478bd9Sstevel@tonic-gate nifs = 1; 6647c478bd9Sstevel@tonic-gate } else { 6657c478bd9Sstevel@tonic-gate old_ifneta = ifneta; 6667c478bd9Sstevel@tonic-gate nifs++; 6677c478bd9Sstevel@tonic-gate ifneta = (struct ifnet **)realloc(ifneta, 668ab25eeb5Syz155240 (nifs + 1) * sizeof(ifp)); 6697c478bd9Sstevel@tonic-gate if (!ifneta) { 6707c478bd9Sstevel@tonic-gate free(old_ifneta); 6717c478bd9Sstevel@tonic-gate nifs = 0; 6727c478bd9Sstevel@tonic-gate return NULL; 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate ifneta[nifs] = NULL; 6757c478bd9Sstevel@tonic-gate ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 6767c478bd9Sstevel@tonic-gate if (!ifneta[nifs - 1]) { 6777c478bd9Sstevel@tonic-gate nifs--; 6787c478bd9Sstevel@tonic-gate return NULL; 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate ifp = ifneta[nifs - 1]; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 684ab25eeb5Syz155240 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 685ab25eeb5Syz155240 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 686ab25eeb5Syz155240 (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 6877c478bd9Sstevel@tonic-gate #else 688ab25eeb5Syz155240 for (s = name; *s && !ISDIGIT(*s); s++) 6897c478bd9Sstevel@tonic-gate ; 690ab25eeb5Syz155240 if (*s && ISDIGIT(*s)) { 6917c478bd9Sstevel@tonic-gate ifp->if_unit = atoi(s); 6927c478bd9Sstevel@tonic-gate ifp->if_name = (char *)malloc(s - name + 1); 6935e985db5Sschuster if (ifp->if_name == NULL) { 6945e985db5Sschuster /* 6955e985db5Sschuster * XXX do it more elegantly: free up mem, 6965e985db5Sschuster * return NULL 6975e985db5Sschuster */ 6985e985db5Sschuster perror("malloc"); 6995e985db5Sschuster exit(1); 7005e985db5Sschuster } 701ab25eeb5Syz155240 (void) strncpy(ifp->if_name, name, s - name); 7027c478bd9Sstevel@tonic-gate ifp->if_name[s - name] = '\0'; 7037c478bd9Sstevel@tonic-gate } else { 7047c478bd9Sstevel@tonic-gate ifp->if_name = strdup(name); 7057c478bd9Sstevel@tonic-gate ifp->if_unit = -1; 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate #endif 7087c478bd9Sstevel@tonic-gate ifp->if_output = no_output; 709ab25eeb5Syz155240 710ab25eeb5Syz155240 if (addr != NULL) { 711ab25eeb5Syz155240 fr_setifpaddr(ifp, addr); 712ab25eeb5Syz155240 } 713ab25eeb5Syz155240 7147c478bd9Sstevel@tonic-gate return ifp; 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate char *get_ifname(ifp) 7197c478bd9Sstevel@tonic-gate struct ifnet *ifp; 7207c478bd9Sstevel@tonic-gate { 7217c478bd9Sstevel@tonic-gate static char ifname[LIFNAMSIZ]; 7227c478bd9Sstevel@tonic-gate 723ab25eeb5Syz155240 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \ 724ab25eeb5Syz155240 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 7257c478bd9Sstevel@tonic-gate sprintf(ifname, "%s", ifp->if_xname); 7267c478bd9Sstevel@tonic-gate #else 7277c478bd9Sstevel@tonic-gate sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 7287c478bd9Sstevel@tonic-gate #endif 7297c478bd9Sstevel@tonic-gate return ifname; 7307c478bd9Sstevel@tonic-gate } 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate void init_ifp() 7357c478bd9Sstevel@tonic-gate { 736ab25eeb5Syz155240 struct ifnet *ifp, **ifpp; 7377c478bd9Sstevel@tonic-gate char fname[32]; 7387c478bd9Sstevel@tonic-gate int fd; 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 741ab25eeb5Syz155240 (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 742ab25eeb5Syz155240 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 743ab25eeb5Syz155240 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 7447c478bd9Sstevel@tonic-gate ifp->if_output = write_output; 7457c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s", ifp->if_xname); 7467c478bd9Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 7477c478bd9Sstevel@tonic-gate if (fd == -1) 7487c478bd9Sstevel@tonic-gate perror("open"); 7497c478bd9Sstevel@tonic-gate else 7507c478bd9Sstevel@tonic-gate close(fd); 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate #else 7537c478bd9Sstevel@tonic-gate 754ab25eeb5Syz155240 for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 7557c478bd9Sstevel@tonic-gate ifp->if_output = write_output; 7567c478bd9Sstevel@tonic-gate sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 7577c478bd9Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 7587c478bd9Sstevel@tonic-gate if (fd == -1) 7597c478bd9Sstevel@tonic-gate perror("open"); 7607c478bd9Sstevel@tonic-gate else 7617c478bd9Sstevel@tonic-gate close(fd); 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate #endif 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate int fr_fastroute(m, mpp, fin, fdp) 7687c478bd9Sstevel@tonic-gate mb_t *m, **mpp; 7697c478bd9Sstevel@tonic-gate fr_info_t *fin; 7707c478bd9Sstevel@tonic-gate frdest_t *fdp; 7717c478bd9Sstevel@tonic-gate { 7727c478bd9Sstevel@tonic-gate struct ifnet *ifp = fdp->fd_ifp; 7737c478bd9Sstevel@tonic-gate ip_t *ip = fin->fin_ip; 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate if (!ifp) 7767c478bd9Sstevel@tonic-gate return 0; /* no routing table out here */ 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate ip->ip_len = htons((u_short)ip->ip_len); 7797c478bd9Sstevel@tonic-gate ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 7807c478bd9Sstevel@tonic-gate ip->ip_sum = 0; 781ab25eeb5Syz155240 #if defined(__sgi) && (IRIX < 60500) 7827c478bd9Sstevel@tonic-gate (*ifp->if_output)(ifp, (void *)ip, NULL); 7837c478bd9Sstevel@tonic-gate # if TRU64 >= 1885 7847c478bd9Sstevel@tonic-gate (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 7857c478bd9Sstevel@tonic-gate # else 7867c478bd9Sstevel@tonic-gate (*ifp->if_output)(ifp, (void *)m, NULL, 0); 7877c478bd9Sstevel@tonic-gate # endif 7887c478bd9Sstevel@tonic-gate #endif 7897c478bd9Sstevel@tonic-gate return 0; 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate int fr_send_reset(fin) 7947c478bd9Sstevel@tonic-gate fr_info_t *fin; 7957c478bd9Sstevel@tonic-gate { 7967c478bd9Sstevel@tonic-gate verbose("- TCP RST sent\n"); 7977c478bd9Sstevel@tonic-gate return 0; 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate int fr_send_icmp_err(type, fin, dst) 8027c478bd9Sstevel@tonic-gate int type; 8037c478bd9Sstevel@tonic-gate fr_info_t *fin; 8047c478bd9Sstevel@tonic-gate int dst; 8057c478bd9Sstevel@tonic-gate { 806ab25eeb5Syz155240 verbose("- ICMP unreachable sent\n"); 8077c478bd9Sstevel@tonic-gate return 0; 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate 811f4b3ec61Sdh155122 void frsync(command, version, nic, data, ifs) 812381a2a9aSdr146992 int command, version; 813381a2a9aSdr146992 void *nic; 814381a2a9aSdr146992 char *data; 815f4b3ec61Sdh155122 ipf_stack_t *ifs; 8167c478bd9Sstevel@tonic-gate { 8177c478bd9Sstevel@tonic-gate return; 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate void m_freem(m) 8227c478bd9Sstevel@tonic-gate mb_t *m; 8237c478bd9Sstevel@tonic-gate { 8247c478bd9Sstevel@tonic-gate return; 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate void m_copydata(m, off, len, cp) 8297c478bd9Sstevel@tonic-gate mb_t *m; 8307c478bd9Sstevel@tonic-gate int off, len; 8317c478bd9Sstevel@tonic-gate caddr_t cp; 8327c478bd9Sstevel@tonic-gate { 8337c478bd9Sstevel@tonic-gate bcopy((char *)m + off, cp, len); 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate int ipfuiomove(buf, len, rwflag, uio) 8387c478bd9Sstevel@tonic-gate caddr_t buf; 8397c478bd9Sstevel@tonic-gate int len, rwflag; 8407c478bd9Sstevel@tonic-gate struct uio *uio; 8417c478bd9Sstevel@tonic-gate { 8427c478bd9Sstevel@tonic-gate int left, ioc, num, offset; 8437c478bd9Sstevel@tonic-gate struct iovec *io; 8447c478bd9Sstevel@tonic-gate char *start; 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate if (rwflag == UIO_READ) { 8477c478bd9Sstevel@tonic-gate left = len; 8487c478bd9Sstevel@tonic-gate ioc = 0; 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate offset = uio->uio_offset; 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate while ((left > 0) && (ioc < uio->uio_iovcnt)) { 8537c478bd9Sstevel@tonic-gate io = uio->uio_iov + ioc; 8547c478bd9Sstevel@tonic-gate num = io->iov_len; 8557c478bd9Sstevel@tonic-gate if (num > left) 8567c478bd9Sstevel@tonic-gate num = left; 8577c478bd9Sstevel@tonic-gate start = (char *)io->iov_base + offset; 8587c478bd9Sstevel@tonic-gate if (start > (char *)io->iov_base + io->iov_len) { 8597c478bd9Sstevel@tonic-gate offset -= io->iov_len; 8607c478bd9Sstevel@tonic-gate ioc++; 8617c478bd9Sstevel@tonic-gate continue; 8627c478bd9Sstevel@tonic-gate } 8637c478bd9Sstevel@tonic-gate bcopy(buf, start, num); 8647c478bd9Sstevel@tonic-gate uio->uio_resid -= num; 8657c478bd9Sstevel@tonic-gate uio->uio_offset += num; 8667c478bd9Sstevel@tonic-gate left -= num; 8677c478bd9Sstevel@tonic-gate if (left > 0) 8687c478bd9Sstevel@tonic-gate ioc++; 8697c478bd9Sstevel@tonic-gate } 8707c478bd9Sstevel@tonic-gate if (left > 0) 8717c478bd9Sstevel@tonic-gate return EFAULT; 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate return 0; 8747c478bd9Sstevel@tonic-gate } 8757c478bd9Sstevel@tonic-gate 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate u_32_t fr_newisn(fin) 8787c478bd9Sstevel@tonic-gate fr_info_t *fin; 8797c478bd9Sstevel@tonic-gate { 8807c478bd9Sstevel@tonic-gate static int iss_seq_off = 0; 8817c478bd9Sstevel@tonic-gate u_char hash[16]; 8827c478bd9Sstevel@tonic-gate u_32_t newiss; 8837c478bd9Sstevel@tonic-gate MD5_CTX ctx; 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate /* 8867c478bd9Sstevel@tonic-gate * Compute the base value of the ISS. It is a hash 8877c478bd9Sstevel@tonic-gate * of (saddr, sport, daddr, dport, secret). 8887c478bd9Sstevel@tonic-gate */ 8897c478bd9Sstevel@tonic-gate MD5Init(&ctx); 8907c478bd9Sstevel@tonic-gate 8917c478bd9Sstevel@tonic-gate MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 8927c478bd9Sstevel@tonic-gate sizeof(fin->fin_fi.fi_src)); 8937c478bd9Sstevel@tonic-gate MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 8947c478bd9Sstevel@tonic-gate sizeof(fin->fin_fi.fi_dst)); 8957c478bd9Sstevel@tonic-gate MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate MD5Final(hash, &ctx); 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate memcpy(&newiss, hash, sizeof(newiss)); 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate /* 9047c478bd9Sstevel@tonic-gate * Now increment our "timer", and add it in to 9057c478bd9Sstevel@tonic-gate * the computed value. 9067c478bd9Sstevel@tonic-gate * 9077c478bd9Sstevel@tonic-gate * XXX Use `addin'? 9087c478bd9Sstevel@tonic-gate * XXX TCP_ISSINCR too large to use? 9097c478bd9Sstevel@tonic-gate */ 9107c478bd9Sstevel@tonic-gate iss_seq_off += 0x00010000; 9117c478bd9Sstevel@tonic-gate newiss += iss_seq_off; 9127c478bd9Sstevel@tonic-gate return newiss; 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 9177c478bd9Sstevel@tonic-gate /* Function: fr_nextipid */ 9187c478bd9Sstevel@tonic-gate /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 9197c478bd9Sstevel@tonic-gate /* Parameters: fin(I) - pointer to packet information */ 9207c478bd9Sstevel@tonic-gate /* */ 9217c478bd9Sstevel@tonic-gate /* Returns the next IPv4 ID to use for this packet. */ 9227c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 9237c478bd9Sstevel@tonic-gate INLINE u_short fr_nextipid(fin) 9247c478bd9Sstevel@tonic-gate fr_info_t *fin; 9257c478bd9Sstevel@tonic-gate { 9267c478bd9Sstevel@tonic-gate static u_short ipid = 0; 9277c478bd9Sstevel@tonic-gate u_short id; 928f4b3ec61Sdh155122 ipf_stack_t *ifs = fin->fin_ifs; 9297c478bd9Sstevel@tonic-gate 930f4b3ec61Sdh155122 MUTEX_ENTER(&ifs->ifs_ipf_rw); 9317c478bd9Sstevel@tonic-gate id = ipid++; 932f4b3ec61Sdh155122 MUTEX_EXIT(&ifs->ifs_ipf_rw); 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate return id; 9357c478bd9Sstevel@tonic-gate } 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate INLINE void fr_checkv4sum(fin) 9397c478bd9Sstevel@tonic-gate fr_info_t *fin; 9407c478bd9Sstevel@tonic-gate { 9417c478bd9Sstevel@tonic-gate if (fr_checkl4sum(fin) == -1) 9427c478bd9Sstevel@tonic-gate fin->fin_flx |= FI_BAD; 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate #ifdef USE_INET6 9477c478bd9Sstevel@tonic-gate INLINE void fr_checkv6sum(fin) 9487c478bd9Sstevel@tonic-gate fr_info_t *fin; 9497c478bd9Sstevel@tonic-gate { 9507c478bd9Sstevel@tonic-gate if (fr_checkl4sum(fin) == -1) 9517c478bd9Sstevel@tonic-gate fin->fin_flx |= FI_BAD; 9527c478bd9Sstevel@tonic-gate } 9537c478bd9Sstevel@tonic-gate #endif 954ab25eeb5Syz155240 955ab25eeb5Syz155240 956ab25eeb5Syz155240 /* 957ab25eeb5Syz155240 * See above for description, except that all addressing is in user space. 958ab25eeb5Syz155240 */ 959ab25eeb5Syz155240 int copyoutptr(src, dst, size) 960ab25eeb5Syz155240 void *src, *dst; 961ab25eeb5Syz155240 size_t size; 962ab25eeb5Syz155240 { 963ab25eeb5Syz155240 caddr_t ca; 964ab25eeb5Syz155240 965ab25eeb5Syz155240 bcopy(dst, (char *)&ca, sizeof(ca)); 966ab25eeb5Syz155240 bcopy(src, ca, size); 967ab25eeb5Syz155240 return 0; 968ab25eeb5Syz155240 } 969ab25eeb5Syz155240 970ab25eeb5Syz155240 971ab25eeb5Syz155240 /* 972ab25eeb5Syz155240 * See above for description, except that all addressing is in user space. 973ab25eeb5Syz155240 */ 974ab25eeb5Syz155240 int copyinptr(src, dst, size) 975ab25eeb5Syz155240 void *src, *dst; 976ab25eeb5Syz155240 size_t size; 977ab25eeb5Syz155240 { 978ab25eeb5Syz155240 caddr_t ca; 979ab25eeb5Syz155240 980ab25eeb5Syz155240 bcopy(src, (char *)&ca, sizeof(ca)); 981ab25eeb5Syz155240 bcopy(ca, dst, size); 982ab25eeb5Syz155240 return 0; 983ab25eeb5Syz155240 } 984ab25eeb5Syz155240 985ab25eeb5Syz155240 986ab25eeb5Syz155240 /* 987ab25eeb5Syz155240 * return the first IP Address associated with an interface 988ab25eeb5Syz155240 */ 989f4b3ec61Sdh155122 int fr_ifpaddr(v, atype, ifptr, inp, inpmask, ifs) 990ab25eeb5Syz155240 int v, atype; 991ab25eeb5Syz155240 void *ifptr; 992ab25eeb5Syz155240 struct in_addr *inp, *inpmask; 993f4b3ec61Sdh155122 ipf_stack_t *ifs; 994ab25eeb5Syz155240 { 995ab25eeb5Syz155240 struct ifnet *ifp = ifptr; 996ab25eeb5Syz155240 #ifdef __sgi 997ab25eeb5Syz155240 struct in_ifaddr *ifa; 998ab25eeb5Syz155240 #else 999ab25eeb5Syz155240 struct ifaddr *ifa; 1000ab25eeb5Syz155240 #endif 1001ab25eeb5Syz155240 1002ab25eeb5Syz155240 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 1003ab25eeb5Syz155240 ifa = ifp->if_addrlist.tqh_first; 1004ab25eeb5Syz155240 #else 1005ab25eeb5Syz155240 # ifdef __sgi 1006ab25eeb5Syz155240 ifa = (struct in_ifaddr *)ifp->in_ifaddr; 1007ab25eeb5Syz155240 # else 1008ab25eeb5Syz155240 ifa = ifp->if_addrlist; 1009ab25eeb5Syz155240 # endif 1010ab25eeb5Syz155240 #endif 1011ab25eeb5Syz155240 if (ifa != NULL) { 1012ab25eeb5Syz155240 struct sockaddr_in *sin, mask; 1013ab25eeb5Syz155240 1014ab25eeb5Syz155240 mask.sin_addr.s_addr = 0xffffffff; 1015ab25eeb5Syz155240 1016ab25eeb5Syz155240 #ifdef __sgi 1017ab25eeb5Syz155240 sin = (struct sockaddr_in *)&ifa->ia_addr; 1018ab25eeb5Syz155240 #else 1019ab25eeb5Syz155240 sin = (struct sockaddr_in *)&ifa->ifa_addr; 1020ab25eeb5Syz155240 #endif 1021ab25eeb5Syz155240 1022ab25eeb5Syz155240 return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask); 1023ab25eeb5Syz155240 } 1024ab25eeb5Syz155240 return 0; 1025ab25eeb5Syz155240 } 1026ab073b32Sdr146992 1027ab073b32Sdr146992 1028ab073b32Sdr146992 /* 1029ab073b32Sdr146992 * This function is not meant to be random, rather just produce a 1030ab073b32Sdr146992 * sequence of numbers that isn't linear to show "randomness". 1031ab073b32Sdr146992 */ 1032ab073b32Sdr146992 u_32_t ipf_random() 1033ab073b32Sdr146992 { 1034ab073b32Sdr146992 static u_int last = 0xa5a5a5a5; 1035ab073b32Sdr146992 static int calls = 0; 1036ab073b32Sdr146992 int number; 1037ab073b32Sdr146992 1038ab073b32Sdr146992 calls++; 1039ab073b32Sdr146992 1040ab073b32Sdr146992 /* 1041ab073b32Sdr146992 * These are deliberately chosen to ensure that there is some 1042ab073b32Sdr146992 * attempt to test whether the output covers the range in test n18. 1043ab073b32Sdr146992 */ 1044ab073b32Sdr146992 switch (calls) 1045ab073b32Sdr146992 { 1046ab073b32Sdr146992 case 1 : 1047ab073b32Sdr146992 number = 0; 1048ab073b32Sdr146992 break; 1049ab073b32Sdr146992 case 2 : 1050ab073b32Sdr146992 number = 4; 1051ab073b32Sdr146992 break; 1052ab073b32Sdr146992 case 3 : 1053ab073b32Sdr146992 number = 3999; 1054ab073b32Sdr146992 break; 1055ab073b32Sdr146992 case 4 : 1056ab073b32Sdr146992 number = 4000; 1057ab073b32Sdr146992 break; 1058ab073b32Sdr146992 case 5 : 1059ab073b32Sdr146992 number = 48999; 1060ab073b32Sdr146992 break; 1061ab073b32Sdr146992 case 6 : 1062ab073b32Sdr146992 number = 49000; 1063ab073b32Sdr146992 break; 1064ab073b32Sdr146992 default : 1065ab073b32Sdr146992 number = last; 1066ab073b32Sdr146992 last *= calls; 1067ab073b32Sdr146992 last++; 1068ab073b32Sdr146992 number ^= last; 1069ab073b32Sdr146992 break; 1070ab073b32Sdr146992 } 1071ab073b32Sdr146992 return number; 1072ab073b32Sdr146992 } 1073