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
iplattach(ifs)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
ipldetach(ifs)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
frzerostats(data,ifs)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 */
iplioctl(dev,cmd,data,mode)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
fr_forgetifp(ifp,ifs)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
fr_resolvedest(fdp,v,ifs)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)
no_output(ifp,m,s)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)
write_output(ifp,m,s)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
fr_setifpaddr(ifp,addr)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*/
get_unit(name,v,ifs)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
get_ifname(ifp)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
init_ifp()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
fr_fastroute(m,mpp,fin,fdp)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
fr_send_reset(fin)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
fr_send_icmp_err(type,fin,dst)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
frsync(command,version,nic,data,ifs)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
m_freem(m)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
m_copydata(m,off,len,cp)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
ipfuiomove(buf,len,rwflag,uio)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
fr_newisn(fin)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 /* ------------------------------------------------------------------------ */
fr_nextipid(fin)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
fr_checkv4sum(fin)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
fr_checkv6sum(fin)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 */
copyoutptr(src,dst,size)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 */
copyinptr(src,dst,size)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 */
fr_ifpaddr(v,atype,ifptr,inp,inpmask,ifs)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 */
ipf_random()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