xref: /onnv-gate/usr/src/uts/common/inet/ipf/solaris.c (revision 10587:e0d280fab007)
12393Syz155240 /*
22393Syz155240  * Copyright (C) 1993-2001, 2003 by Darren Reed.
32393Syz155240  *
42393Syz155240  * See the IPFILTER.LICENCE file for details on licencing.
52393Syz155240  *
6*10587SAlexandr.Nedvedicky@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
72393Syz155240  * Use is subject to license terms.
82393Syz155240  */
92393Syz155240 
102393Syz155240 #include <sys/systm.h>
112393Syz155240 #include <sys/types.h>
122393Syz155240 #include <sys/param.h>
132393Syz155240 #include <sys/errno.h>
142393Syz155240 #include <sys/uio.h>
152393Syz155240 #include <sys/buf.h>
162393Syz155240 #include <sys/modctl.h>
172393Syz155240 #include <sys/open.h>
182393Syz155240 #include <sys/kmem.h>
192393Syz155240 #include <sys/conf.h>
202393Syz155240 #include <sys/cmn_err.h>
212393Syz155240 #include <sys/stat.h>
222393Syz155240 #include <sys/cred.h>
232393Syz155240 #include <sys/dditypes.h>
242393Syz155240 #include <sys/poll.h>
252393Syz155240 #include <sys/autoconf.h>
262393Syz155240 #include <sys/byteorder.h>
272393Syz155240 #include <sys/socket.h>
282393Syz155240 #include <sys/dlpi.h>
292393Syz155240 #include <sys/stropts.h>
302393Syz155240 #include <sys/kstat.h>
312393Syz155240 #include <sys/sockio.h>
322958Sdr146992 #include <sys/neti.h>
332958Sdr146992 #include <sys/hook.h>
342393Syz155240 #include <net/if.h>
352393Syz155240 #if SOLARIS2 >= 6
367656SSherry.Moore@Sun.COM #include <net/if_types.h>
372393Syz155240 #endif
382393Syz155240 #include <net/af.h>
392393Syz155240 #include <net/route.h>
402393Syz155240 #include <netinet/in.h>
412393Syz155240 #include <netinet/in_systm.h>
422393Syz155240 #include <netinet/if_ether.h>
432393Syz155240 #include <netinet/ip.h>
442393Syz155240 #include <netinet/ip_var.h>
452393Syz155240 #include <netinet/tcp.h>
462393Syz155240 #include <netinet/udp.h>
472393Syz155240 #include <netinet/tcpip.h>
482393Syz155240 #include <netinet/ip_icmp.h>
492393Syz155240 #include <sys/ddi.h>
502393Syz155240 #include <sys/sunddi.h>
512393Syz155240 #include "netinet/ip_compat.h"
522393Syz155240 #include "netinet/ipl.h"
532393Syz155240 #include "netinet/ip_fil.h"
542393Syz155240 #include "netinet/ip_nat.h"
552393Syz155240 #include "netinet/ip_frag.h"
562393Syz155240 #include "netinet/ip_auth.h"
572393Syz155240 #include "netinet/ip_state.h"
583448Sdh155122 #include "netinet/ipf_stack.h"
592393Syz155240 
602393Syz155240 extern	int	iplwrite __P((dev_t, struct uio *, cred_t *));
612393Syz155240 
622393Syz155240 static	int	ipf_getinfo __P((dev_info_t *, ddi_info_cmd_t,
637656SSherry.Moore@Sun.COM 		    void *, void **));
642393Syz155240 #if SOLARIS2 < 10
652393Syz155240 static	int	ipf_identify __P((dev_info_t *));
662393Syz155240 #endif
672393Syz155240 static	int	ipf_attach __P((dev_info_t *, ddi_attach_cmd_t));
682393Syz155240 static	int	ipf_detach __P((dev_info_t *, ddi_detach_cmd_t));
697513SDarren.Reed@Sun.COM static	void	*ipf_stack_create __P((const netid_t));
707513SDarren.Reed@Sun.COM static	void	ipf_stack_destroy __P((const netid_t, void *));
717915SDarren.Reed@Sun.COM static	void	ipf_stack_shutdown __P((const netid_t, void *));
723448Sdh155122 static	int	ipf_property_g_update __P((dev_info_t *));
732393Syz155240 static	char	*ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
742393Syz155240 				    IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
752393Syz155240 				    IPLOOKUP_NAME, NULL };
762393Syz155240 
772393Syz155240 
782393Syz155240 static struct cb_ops ipf_cb_ops = {
792393Syz155240 	iplopen,
802393Syz155240 	iplclose,
812393Syz155240 	nodev,		/* strategy */
822393Syz155240 	nodev,		/* print */
832393Syz155240 	nodev,		/* dump */
842393Syz155240 	iplread,
852393Syz155240 	iplwrite,	/* write */
862393Syz155240 	iplioctl,	/* ioctl */
872393Syz155240 	nodev,		/* devmap */
882393Syz155240 	nodev,		/* mmap */
892393Syz155240 	nodev,		/* segmap */
902393Syz155240 	nochpoll,	/* poll */
912393Syz155240 	ddi_prop_op,
922393Syz155240 	NULL,
932393Syz155240 	D_MTSAFE,
942393Syz155240 #if SOLARIS2 > 4
952393Syz155240 	CB_REV,
962393Syz155240 	nodev,		/* aread */
972393Syz155240 	nodev,		/* awrite */
982393Syz155240 #endif
992393Syz155240 };
1002393Syz155240 
1012393Syz155240 static struct dev_ops ipf_ops = {
1022393Syz155240 	DEVO_REV,
1032393Syz155240 	0,
1042393Syz155240 	ipf_getinfo,
1052393Syz155240 #if SOLARIS2 >= 10
1062393Syz155240 	nulldev,
1072393Syz155240 #else
1082393Syz155240 	ipf_identify,
1092393Syz155240 #endif
1102393Syz155240 	nulldev,
1112393Syz155240 	ipf_attach,
1122393Syz155240 	ipf_detach,
1132393Syz155240 	nodev,		/* reset */
1142393Syz155240 	&ipf_cb_ops,
1157656SSherry.Moore@Sun.COM 	(struct bus_ops *)0,
1167656SSherry.Moore@Sun.COM 	NULL,
1177656SSherry.Moore@Sun.COM 	ddi_quiesce_not_needed,		/* quiesce */
1182393Syz155240 };
1192393Syz155240 
1207513SDarren.Reed@Sun.COM 
1217513SDarren.Reed@Sun.COM static net_instance_t *ipfncb = NULL;
1227513SDarren.Reed@Sun.COM static ipf_stack_t *ipf_stacks = NULL;
1237513SDarren.Reed@Sun.COM static kmutex_t ipf_stack_lock;
1242393Syz155240 extern struct mod_ops mod_driverops;
1252393Syz155240 static struct modldrv iplmod = {
1262393Syz155240 	&mod_driverops, IPL_VERSION, &ipf_ops };
1272393Syz155240 static struct modlinkage modlink1 = { MODREV_1, &iplmod, NULL };
1282393Syz155240 
1292393Syz155240 #if SOLARIS2 >= 6
1302393Syz155240 static	size_t	hdrsizes[57][2] = {
1312393Syz155240 	{ 0, 0 },
1322393Syz155240 	{ IFT_OTHER, 0 },
1332393Syz155240 	{ IFT_1822, 0 },
1342393Syz155240 	{ IFT_HDH1822, 0 },
1352393Syz155240 	{ IFT_X25DDN, 0 },
1362393Syz155240 	{ IFT_X25, 0 },
1372393Syz155240 	{ IFT_ETHER, 14 },
1382393Syz155240 	{ IFT_ISO88023, 0 },
1392393Syz155240 	{ IFT_ISO88024, 0 },
1402393Syz155240 	{ IFT_ISO88025, 0 },
1412393Syz155240 	{ IFT_ISO88026, 0 },
1422393Syz155240 	{ IFT_STARLAN, 0 },
1432393Syz155240 	{ IFT_P10, 0 },
1442393Syz155240 	{ IFT_P80, 0 },
1452393Syz155240 	{ IFT_HY, 0 },
1462393Syz155240 	{ IFT_FDDI, 24 },
1472393Syz155240 	{ IFT_LAPB, 0 },
1482393Syz155240 	{ IFT_SDLC, 0 },
1492393Syz155240 	{ IFT_T1, 0 },
1502393Syz155240 	{ IFT_CEPT, 0 },
1512393Syz155240 	{ IFT_ISDNBASIC, 0 },
1522393Syz155240 	{ IFT_ISDNPRIMARY, 0 },
1532393Syz155240 	{ IFT_PTPSERIAL, 0 },
1542393Syz155240 	{ IFT_PPP, 0 },
1552393Syz155240 	{ IFT_LOOP, 0 },
1562393Syz155240 	{ IFT_EON, 0 },
1572393Syz155240 	{ IFT_XETHER, 0 },
1582393Syz155240 	{ IFT_NSIP, 0 },
1592393Syz155240 	{ IFT_SLIP, 0 },
1602393Syz155240 	{ IFT_ULTRA, 0 },
1612393Syz155240 	{ IFT_DS3, 0 },
1622393Syz155240 	{ IFT_SIP, 0 },
1632393Syz155240 	{ IFT_FRELAY, 0 },
1642393Syz155240 	{ IFT_RS232, 0 },
1652393Syz155240 	{ IFT_PARA, 0 },
1662393Syz155240 	{ IFT_ARCNET, 0 },
1672393Syz155240 	{ IFT_ARCNETPLUS, 0 },
1682393Syz155240 	{ IFT_ATM, 0 },
1692393Syz155240 	{ IFT_MIOX25, 0 },
1702393Syz155240 	{ IFT_SONET, 0 },
1712393Syz155240 	{ IFT_X25PLE, 0 },
1722393Syz155240 	{ IFT_ISO88022LLC, 0 },
1732393Syz155240 	{ IFT_LOCALTALK, 0 },
1742393Syz155240 	{ IFT_SMDSDXI, 0 },
1752393Syz155240 	{ IFT_FRELAYDCE, 0 },
1762393Syz155240 	{ IFT_V35, 0 },
1772393Syz155240 	{ IFT_HSSI, 0 },
1782393Syz155240 	{ IFT_HIPPI, 0 },
1792393Syz155240 	{ IFT_MODEM, 0 },
1802393Syz155240 	{ IFT_AAL5, 0 },
1812393Syz155240 	{ IFT_SONETPATH, 0 },
1822393Syz155240 	{ IFT_SONETVT, 0 },
1832393Syz155240 	{ IFT_SMDSICIP, 0 },
1842393Syz155240 	{ IFT_PROPVIRTUAL, 0 },
1852393Syz155240 	{ IFT_PROPMUX, 0 },
1862393Syz155240 };
1872393Syz155240 #endif /* SOLARIS2 >= 6 */
1882393Syz155240 
1893448Sdh155122 dev_info_t *ipf_dev_info = NULL;
1902393Syz155240 
1912393Syz155240 static const filter_kstats_t ipf_kstat_tmp = {
1922393Syz155240 	{ "pass",			KSTAT_DATA_ULONG },
1932393Syz155240 	{ "block",			KSTAT_DATA_ULONG },
1942393Syz155240 	{ "nomatch",			KSTAT_DATA_ULONG },
1952393Syz155240 	{ "short",			KSTAT_DATA_ULONG },
1962393Syz155240 	{ "pass, logged",		KSTAT_DATA_ULONG },
1972393Syz155240 	{ "block, logged",		KSTAT_DATA_ULONG },
1982393Syz155240 	{ "nomatch, logged",		KSTAT_DATA_ULONG },
1992393Syz155240 	{ "logged",			KSTAT_DATA_ULONG },
2002393Syz155240 	{ "skip",			KSTAT_DATA_ULONG },
2012393Syz155240 	{ "return sent",		KSTAT_DATA_ULONG },
2022393Syz155240 	{ "acct",			KSTAT_DATA_ULONG },
2032393Syz155240 	{ "bad frag state alloc",	KSTAT_DATA_ULONG },
2042393Syz155240 	{ "new frag state kept",	KSTAT_DATA_ULONG },
2052393Syz155240 	{ "new frag state compl. pkt",	KSTAT_DATA_ULONG },
2062393Syz155240 	{ "bad pkt state alloc",	KSTAT_DATA_ULONG },
2072393Syz155240 	{ "new pkt kept state",		KSTAT_DATA_ULONG },
2082393Syz155240 	{ "cachehit",			KSTAT_DATA_ULONG },
2092393Syz155240 	{ "tcp cksum bad",		KSTAT_DATA_ULONG },
2102393Syz155240 	{{ "pullup ok",			KSTAT_DATA_ULONG },
2112393Syz155240 	{ "pullup nok",			KSTAT_DATA_ULONG }},
2122393Syz155240 	{ "src != route",		KSTAT_DATA_ULONG },
2132393Syz155240 	{ "ttl invalid",		KSTAT_DATA_ULONG },
2142393Syz155240 	{ "bad ip pkt",			KSTAT_DATA_ULONG },
2152393Syz155240 	{ "ipv6 pkt",			KSTAT_DATA_ULONG },
2162393Syz155240 	{ "dropped:pps ceiling",	KSTAT_DATA_ULONG },
2172393Syz155240 	{ "ip upd. fail",		KSTAT_DATA_ULONG }
2182393Syz155240 };
2192393Syz155240 
2202958Sdr146992 
2212393Syz155240 static int	ipf_kstat_update(kstat_t *ksp, int rwflag);
2222393Syz155240 
2232393Syz155240 static void
ipf_kstat_init(ipf_stack_t * ifs)2247513SDarren.Reed@Sun.COM ipf_kstat_init(ipf_stack_t *ifs)
2252393Syz155240 {
2267513SDarren.Reed@Sun.COM 	ifs->ifs_kstatp[0] = net_kstat_create(ifs->ifs_netid, "ipf", 0,
2277513SDarren.Reed@Sun.COM 	    "inbound", "net", KSTAT_TYPE_NAMED,
2287513SDarren.Reed@Sun.COM 	    sizeof (filter_kstats_t) / sizeof (kstat_named_t), 0);
2297513SDarren.Reed@Sun.COM 	if (ifs->ifs_kstatp[0] != NULL) {
2307513SDarren.Reed@Sun.COM 		bcopy(&ipf_kstat_tmp, ifs->ifs_kstatp[0]->ks_data,
2317513SDarren.Reed@Sun.COM 		    sizeof (filter_kstats_t));
2327513SDarren.Reed@Sun.COM 		ifs->ifs_kstatp[0]->ks_update = ipf_kstat_update;
2337513SDarren.Reed@Sun.COM 		ifs->ifs_kstatp[0]->ks_private = &ifs->ifs_frstats[0];
2347513SDarren.Reed@Sun.COM 		kstat_install(ifs->ifs_kstatp[0]);
2357513SDarren.Reed@Sun.COM 	}
2362393Syz155240 
2377513SDarren.Reed@Sun.COM 	ifs->ifs_kstatp[1] = net_kstat_create(ifs->ifs_netid, "ipf", 0,
2387513SDarren.Reed@Sun.COM 	    "outbound", "net", KSTAT_TYPE_NAMED,
2397513SDarren.Reed@Sun.COM 	    sizeof (filter_kstats_t) / sizeof (kstat_named_t), 0);
2407513SDarren.Reed@Sun.COM 	if (ifs->ifs_kstatp[1] != NULL) {
2417513SDarren.Reed@Sun.COM 		bcopy(&ipf_kstat_tmp, ifs->ifs_kstatp[1]->ks_data,
2427513SDarren.Reed@Sun.COM 		    sizeof (filter_kstats_t));
2437513SDarren.Reed@Sun.COM 		ifs->ifs_kstatp[1]->ks_update = ipf_kstat_update;
2447513SDarren.Reed@Sun.COM 		ifs->ifs_kstatp[1]->ks_private = &ifs->ifs_frstats[1];
2457513SDarren.Reed@Sun.COM 		kstat_install(ifs->ifs_kstatp[1]);
2462393Syz155240 	}
2472393Syz155240 
2482393Syz155240 #ifdef	IPFDEBUG
2497513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter: ipf_kstat_init(%p) installed %p, %p",
2507656SSherry.Moore@Sun.COM 	    ifs, ifs->ifs_kstatp[0], ifs->ifs_kstatp[1]);
2512393Syz155240 #endif
2522393Syz155240 }
2532393Syz155240 
2547513SDarren.Reed@Sun.COM 
2552393Syz155240 static void
ipf_kstat_fini(ipf_stack_t * ifs)2567513SDarren.Reed@Sun.COM ipf_kstat_fini(ipf_stack_t *ifs)
2572393Syz155240 {
2582393Syz155240 	int i;
2593448Sdh155122 
2602393Syz155240 	for (i = 0; i < 2; i++) {
2613448Sdh155122 		if (ifs->ifs_kstatp[i] != NULL) {
2627513SDarren.Reed@Sun.COM 			net_kstat_delete(ifs->ifs_netid, ifs->ifs_kstatp[i]);
2633448Sdh155122 			ifs->ifs_kstatp[i] = NULL;
2642393Syz155240 		}
2652393Syz155240 	}
2662393Syz155240 }
2672393Syz155240 
2687513SDarren.Reed@Sun.COM 
2692393Syz155240 static int
ipf_kstat_update(kstat_t * ksp,int rwflag)2702393Syz155240 ipf_kstat_update(kstat_t *ksp, int rwflag)
2712393Syz155240 {
2722393Syz155240 	filter_kstats_t	*fkp;
2732393Syz155240 	filterstats_t	*fsp;
2742393Syz155240 
2753448Sdh155122 	if (ksp == NULL || ksp->ks_data == NULL)
2763448Sdh155122 		return (EIO);
2773448Sdh155122 
2782393Syz155240 	if (rwflag == KSTAT_WRITE)
2792393Syz155240 		return (EACCES);
2802393Syz155240 
2812393Syz155240 	fkp = ksp->ks_data;
2822393Syz155240 	fsp = ksp->ks_private;
2832393Syz155240 
2842393Syz155240 	fkp->fks_pass.value.ul		= fsp->fr_pass;
2852393Syz155240 	fkp->fks_block.value.ul		= fsp->fr_block;
2862393Syz155240 	fkp->fks_nom.value.ul		= fsp->fr_nom;
2872393Syz155240 	fkp->fks_short.value.ul		= fsp->fr_short;
2882393Syz155240 	fkp->fks_ppkl.value.ul		= fsp->fr_ppkl;
2892393Syz155240 	fkp->fks_bpkl.value.ul		= fsp->fr_bpkl;
2902393Syz155240 	fkp->fks_npkl.value.ul		= fsp->fr_npkl;
2912393Syz155240 	fkp->fks_pkl.value.ul		= fsp->fr_pkl;
2922393Syz155240 	fkp->fks_skip.value.ul		= fsp->fr_skip;
2932393Syz155240 	fkp->fks_ret.value.ul		= fsp->fr_ret;
2942393Syz155240 	fkp->fks_acct.value.ul		= fsp->fr_acct;
2952393Syz155240 	fkp->fks_bnfr.value.ul		= fsp->fr_bnfr;
2962393Syz155240 	fkp->fks_nfr.value.ul		= fsp->fr_nfr;
2972393Syz155240 	fkp->fks_cfr.value.ul		= fsp->fr_cfr;
2982393Syz155240 	fkp->fks_bads.value.ul		= fsp->fr_bads;
2992393Syz155240 	fkp->fks_ads.value.ul		= fsp->fr_ads;
3002393Syz155240 	fkp->fks_chit.value.ul		= fsp->fr_chit;
3012393Syz155240 	fkp->fks_tcpbad.value.ul 	= fsp->fr_tcpbad;
3022393Syz155240 	fkp->fks_pull[0].value.ul 	= fsp->fr_pull[0];
3032393Syz155240 	fkp->fks_pull[1].value.ul 	= fsp->fr_pull[1];
3042393Syz155240 	fkp->fks_badsrc.value.ul 	= fsp->fr_badsrc;
3052393Syz155240 	fkp->fks_badttl.value.ul 	= fsp->fr_badttl;
3062393Syz155240 	fkp->fks_bad.value.ul		= fsp->fr_bad;
3072393Syz155240 	fkp->fks_ipv6.value.ul		= fsp->fr_ipv6;
3082393Syz155240 	fkp->fks_ppshit.value.ul 	= fsp->fr_ppshit;
3092393Syz155240 	fkp->fks_ipud.value.ul		= fsp->fr_ipud;
3102393Syz155240 
3112393Syz155240 	return (0);
3122393Syz155240 }
3132393Syz155240 
3147656SSherry.Moore@Sun.COM int
_init()3157656SSherry.Moore@Sun.COM _init()
3162393Syz155240 {
3172393Syz155240 	int ipfinst;
3182393Syz155240 
3192393Syz155240 	ipfinst = mod_install(&modlink1);
3202393Syz155240 #ifdef	IPFDEBUG
3212393Syz155240 	cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
3222393Syz155240 #endif
3237513SDarren.Reed@Sun.COM 	mutex_init(&ipf_stack_lock, NULL, MUTEX_DRIVER, NULL);
3247656SSherry.Moore@Sun.COM 	return (ipfinst);
3252393Syz155240 }
3262393Syz155240 
3272393Syz155240 
3287656SSherry.Moore@Sun.COM int
_fini(void)3297656SSherry.Moore@Sun.COM _fini(void)
3302393Syz155240 {
3312393Syz155240 	int ipfinst;
3322393Syz155240 
3332393Syz155240 	ipfinst = mod_remove(&modlink1);
3342393Syz155240 #ifdef	IPFDEBUG
3352393Syz155240 	cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
3362393Syz155240 #endif
3377656SSherry.Moore@Sun.COM 	return (ipfinst);
3382393Syz155240 }
3392393Syz155240 
3402393Syz155240 
3417656SSherry.Moore@Sun.COM int
_info(modinfop)3427656SSherry.Moore@Sun.COM _info(modinfop)
3432393Syz155240 struct modinfo *modinfop;
3442393Syz155240 {
3452393Syz155240 	int ipfinst;
3462393Syz155240 
3472393Syz155240 	ipfinst = mod_info(&modlink1, modinfop);
3482393Syz155240 #ifdef	IPFDEBUG
3497513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter: _info(%p) = %d", modinfop, ipfinst);
3502393Syz155240 #endif
3517656SSherry.Moore@Sun.COM 	return (ipfinst);
3522393Syz155240 }
3532393Syz155240 
3542393Syz155240 
3552393Syz155240 #if SOLARIS2 < 10
ipf_identify(dip)3562393Syz155240 static int ipf_identify(dip)
3572393Syz155240 dev_info_t *dip;
3582393Syz155240 {
3597656SSherry.Moore@Sun.COM #ifdef	IPFDEBUG
3607513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter: ipf_identify(%p)", dip);
3617656SSherry.Moore@Sun.COM #endif
3622393Syz155240 	if (strcmp(ddi_get_name(dip), "ipf") == 0)
3632393Syz155240 		return (DDI_IDENTIFIED);
3642393Syz155240 	return (DDI_NOT_IDENTIFIED);
3652393Syz155240 }
3662393Syz155240 #endif
3672393Syz155240 
3683448Sdh155122 /*
3693448Sdh155122  * Initialize things for IPF for each stack instance
3703448Sdh155122  */
3713448Sdh155122 static void *
ipf_stack_create(const netid_t id)3727513SDarren.Reed@Sun.COM ipf_stack_create(const netid_t id)
3733448Sdh155122 {
3743448Sdh155122 	ipf_stack_t	*ifs;
3753448Sdh155122 
3767513SDarren.Reed@Sun.COM #ifdef IPFDEBUG
3777513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter:stack_create id=%d", id);
3783448Sdh155122 #endif
3793448Sdh155122 
3807513SDarren.Reed@Sun.COM 	ifs = (ipf_stack_t *)kmem_alloc(sizeof (*ifs), KM_SLEEP);
3813448Sdh155122 	bzero(ifs, sizeof (*ifs));
3823448Sdh155122 
3833448Sdh155122 	ifs->ifs_hook4_physical_in	= B_FALSE;
3843448Sdh155122 	ifs->ifs_hook4_physical_out	= B_FALSE;
3853448Sdh155122 	ifs->ifs_hook4_nic_events	= B_FALSE;
3863448Sdh155122 	ifs->ifs_hook4_loopback_in	= B_FALSE;
3873448Sdh155122 	ifs->ifs_hook4_loopback_out	= B_FALSE;
3883448Sdh155122 	ifs->ifs_hook6_physical_in	= B_FALSE;
3893448Sdh155122 	ifs->ifs_hook6_physical_out	= B_FALSE;
3903448Sdh155122 	ifs->ifs_hook6_nic_events	= B_FALSE;
3913448Sdh155122 	ifs->ifs_hook6_loopback_in	= B_FALSE;
3923448Sdh155122 	ifs->ifs_hook6_loopback_out	= B_FALSE;
3933448Sdh155122 
3943448Sdh155122 	/*
3953448Sdh155122 	 * Initialize mutex's
3963448Sdh155122 	 */
3973448Sdh155122 	RWLOCK_INIT(&ifs->ifs_ipf_global, "ipf filter load/unload mutex");
3983448Sdh155122 	RWLOCK_INIT(&ifs->ifs_ipf_mutex, "ipf filter rwlock");
399*10587SAlexandr.Nedvedicky@Sun.COM 	RWLOCK_INIT(&ifs->ifs_ipf_frcache, "ipf cache rwlock");
4007513SDarren.Reed@Sun.COM 	ifs->ifs_netid = id;
4017513SDarren.Reed@Sun.COM 	ifs->ifs_zone = net_getzoneidbynetid(id);
4027513SDarren.Reed@Sun.COM 	ipf_kstat_init(ifs);
4037513SDarren.Reed@Sun.COM 
4047513SDarren.Reed@Sun.COM #ifdef IPFDEBUG
4057513SDarren.Reed@Sun.COM 	cmn_err(CE_CONT, "IP Filter:stack_create zone=%d", ifs->ifs_zone);
4063448Sdh155122 #endif
4073448Sdh155122 
4083448Sdh155122 	/*
4093448Sdh155122 	 * Lock people out while we set things up.
4103448Sdh155122 	 */
4113448Sdh155122 	WRITE_ENTER(&ifs->ifs_ipf_global);
4123448Sdh155122 	ipftuneable_alloc(ifs);
4133448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
4143448Sdh155122 
4154287Snordmark 	/* Limit to global stack */
4167513SDarren.Reed@Sun.COM 	if (ifs->ifs_zone == GLOBAL_ZONEID)
4174287Snordmark 		cmn_err(CE_CONT, "!%s, running.\n", ipfilter_version);
4184287Snordmark 
4197513SDarren.Reed@Sun.COM 	mutex_enter(&ipf_stack_lock);
4207513SDarren.Reed@Sun.COM 	if (ipf_stacks != NULL)
4217513SDarren.Reed@Sun.COM 		ipf_stacks->ifs_pnext = &ifs->ifs_next;
4227513SDarren.Reed@Sun.COM 	ifs->ifs_next = ipf_stacks;
4237513SDarren.Reed@Sun.COM 	ifs->ifs_pnext = &ipf_stacks;
4247513SDarren.Reed@Sun.COM 	ipf_stacks = ifs;
4257513SDarren.Reed@Sun.COM 	mutex_exit(&ipf_stack_lock);
4267513SDarren.Reed@Sun.COM 
4273448Sdh155122 	return (ifs);
4283448Sdh155122 }
4293448Sdh155122 
4307513SDarren.Reed@Sun.COM 
4317513SDarren.Reed@Sun.COM /*
4327513SDarren.Reed@Sun.COM  * This function should only ever be used to find the pointer to the
4337513SDarren.Reed@Sun.COM  * ipfilter stack structure for the zone that is currently being
4347513SDarren.Reed@Sun.COM  * executed... so if you're running in the context of zone 1, you
4357513SDarren.Reed@Sun.COM  * should not attempt to find the ipf_stack_t for zone 0 or 2 or
4367513SDarren.Reed@Sun.COM  * anything else but 1.  In that way, the returned pointer is safe
4377513SDarren.Reed@Sun.COM  * as it will only be nuked when the instance is destroyed as part
4387513SDarren.Reed@Sun.COM  * of the final shutdown of a zone.
4397513SDarren.Reed@Sun.COM  */
4407656SSherry.Moore@Sun.COM ipf_stack_t *
ipf_find_stack(const zoneid_t zone)4417656SSherry.Moore@Sun.COM ipf_find_stack(const zoneid_t zone)
4427513SDarren.Reed@Sun.COM {
4437513SDarren.Reed@Sun.COM 	ipf_stack_t *ifs;
4447513SDarren.Reed@Sun.COM 
4457513SDarren.Reed@Sun.COM 	mutex_enter(&ipf_stack_lock);
4467513SDarren.Reed@Sun.COM 	for (ifs = ipf_stacks; ifs != NULL; ifs = ifs->ifs_next) {
4477513SDarren.Reed@Sun.COM 		if (ifs->ifs_zone == zone)
4487513SDarren.Reed@Sun.COM 			break;
4497513SDarren.Reed@Sun.COM 	}
4507513SDarren.Reed@Sun.COM 	mutex_exit(&ipf_stack_lock);
4517656SSherry.Moore@Sun.COM 	return (ifs);
4527513SDarren.Reed@Sun.COM }
4537513SDarren.Reed@Sun.COM 
4547513SDarren.Reed@Sun.COM 
ipf_detach_check_zone(ipf_stack_t * ifs)4553448Sdh155122 static int ipf_detach_check_zone(ipf_stack_t *ifs)
4563448Sdh155122 {
4573448Sdh155122 	/*
4583448Sdh155122 	 * Make sure we're the only one's modifying things.  With
4593448Sdh155122 	 * this lock others should just fall out of the loop.
4603448Sdh155122 	 */
4613448Sdh155122 	READ_ENTER(&ifs->ifs_ipf_global);
4623448Sdh155122 	if (ifs->ifs_fr_running == 1) {
4633448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ipf_global);
4643448Sdh155122 		return (-1);
4653448Sdh155122 	}
4667656SSherry.Moore@Sun.COM 
4673448Sdh155122 	/*
4683448Sdh155122 	 * Make sure there is no active filter rule.
4693448Sdh155122 	 */
4703448Sdh155122 	if (ifs->ifs_ipfilter[0][ifs->ifs_fr_active] ||
4713448Sdh155122 	    ifs->ifs_ipfilter[1][ifs->ifs_fr_active] ||
4723448Sdh155122 	    ifs->ifs_ipfilter6[0][ifs->ifs_fr_active] ||
4733448Sdh155122 	    ifs->ifs_ipfilter6[1][ifs->ifs_fr_active]) {
4743448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ipf_global);
4753448Sdh155122 		return (-1);
4763448Sdh155122 	}
4773448Sdh155122 
4783448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
4793448Sdh155122 
4803448Sdh155122 	return (0);
4813448Sdh155122 }
4823448Sdh155122 
4837513SDarren.Reed@Sun.COM 
ipf_detach_check_all()4843448Sdh155122 static int ipf_detach_check_all()
4853448Sdh155122 {
4867513SDarren.Reed@Sun.COM 	ipf_stack_t *ifs;
4873448Sdh155122 
4887513SDarren.Reed@Sun.COM 	mutex_enter(&ipf_stack_lock);
4897513SDarren.Reed@Sun.COM 	for (ifs = ipf_stacks; ifs != NULL; ifs = ifs->ifs_next)
4907513SDarren.Reed@Sun.COM 		if (ipf_detach_check_zone(ifs) != 0)
4917513SDarren.Reed@Sun.COM 			break;
4927513SDarren.Reed@Sun.COM 	mutex_exit(&ipf_stack_lock);
4937513SDarren.Reed@Sun.COM 	return ((ifs == NULL) ? 0 : -1);
4947513SDarren.Reed@Sun.COM }
4953448Sdh155122 
4963448Sdh155122 
4973448Sdh155122 /*
4983448Sdh155122  * Destroy things for ipf for one stack.
4993448Sdh155122  */
5003448Sdh155122 /* ARGSUSED */
5013448Sdh155122 static void
ipf_stack_shutdown(const netid_t id,void * arg)5027915SDarren.Reed@Sun.COM ipf_stack_shutdown(const netid_t id, void *arg)
5037915SDarren.Reed@Sun.COM {
5047915SDarren.Reed@Sun.COM 	ipf_stack_t *ifs = (ipf_stack_t *)arg;
5057915SDarren.Reed@Sun.COM 
5067915SDarren.Reed@Sun.COM 	ipf_kstat_fini(ifs);
5077915SDarren.Reed@Sun.COM }
5087915SDarren.Reed@Sun.COM 
5097915SDarren.Reed@Sun.COM 
5107915SDarren.Reed@Sun.COM /*
5117915SDarren.Reed@Sun.COM  * Destroy things for ipf for one stack.
5127915SDarren.Reed@Sun.COM  */
5137915SDarren.Reed@Sun.COM /* ARGSUSED */
5147915SDarren.Reed@Sun.COM static void
ipf_stack_destroy(const netid_t id,void * arg)5157513SDarren.Reed@Sun.COM ipf_stack_destroy(const netid_t id, void *arg)
5163448Sdh155122 {
5173448Sdh155122 	ipf_stack_t *ifs = (ipf_stack_t *)arg;
5187513SDarren.Reed@Sun.COM 	timeout_id_t tid;
5193448Sdh155122 
5207513SDarren.Reed@Sun.COM #ifdef IPFDEBUG
5217513SDarren.Reed@Sun.COM 	(void) printf("ipf_stack_destroy(%p)\n", (void *)ifs);
5223448Sdh155122 #endif
5233448Sdh155122 
5243448Sdh155122 	/*
5253448Sdh155122 	 * Make sure we're the only one's modifying things.  With
5263448Sdh155122 	 * this lock others should just fall out of the loop.
5273448Sdh155122 	 */
5283448Sdh155122 	WRITE_ENTER(&ifs->ifs_ipf_global);
5293448Sdh155122 	if (ifs->ifs_fr_running == -2) {
5303448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ipf_global);
5313448Sdh155122 		return;
5323448Sdh155122 	}
5333448Sdh155122 	ifs->ifs_fr_running = -2;
5347513SDarren.Reed@Sun.COM 	tid = ifs->ifs_fr_timer_id;
5357513SDarren.Reed@Sun.COM 	ifs->ifs_fr_timer_id = NULL;
5363448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
5373448Sdh155122 
5387513SDarren.Reed@Sun.COM 	mutex_enter(&ipf_stack_lock);
5397513SDarren.Reed@Sun.COM 	if (ifs->ifs_next != NULL)
5407513SDarren.Reed@Sun.COM 		ifs->ifs_next->ifs_pnext = ifs->ifs_pnext;
5417513SDarren.Reed@Sun.COM 	*ifs->ifs_pnext = ifs->ifs_next;
5427513SDarren.Reed@Sun.COM 	mutex_exit(&ipf_stack_lock);
5437513SDarren.Reed@Sun.COM 
5447513SDarren.Reed@Sun.COM 	if (tid != NULL)
5457513SDarren.Reed@Sun.COM 		(void) untimeout(tid);
5463448Sdh155122 
5473448Sdh155122 	WRITE_ENTER(&ifs->ifs_ipf_global);
5483448Sdh155122 	if (ipldetach(ifs) != 0) {
5497513SDarren.Reed@Sun.COM 		printf("ipf_stack_destroy: ipldetach failed\n");
5503448Sdh155122 	}
5513448Sdh155122 
5523448Sdh155122 	ipftuneable_free(ifs);
5533448Sdh155122 
5543448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
5553448Sdh155122 	RW_DESTROY(&ifs->ifs_ipf_mutex);
556*10587SAlexandr.Nedvedicky@Sun.COM 	RW_DESTROY(&ifs->ifs_ipf_frcache);
5573448Sdh155122 	RW_DESTROY(&ifs->ifs_ipf_global);
5583448Sdh155122 
5593448Sdh155122 	KFREE(ifs);
5603448Sdh155122 }
5612393Syz155240 
5627513SDarren.Reed@Sun.COM 
ipf_attach(dip,cmd)5632393Syz155240 static int ipf_attach(dip, cmd)
5642393Syz155240 dev_info_t *dip;
5652393Syz155240 ddi_attach_cmd_t cmd;
5662393Syz155240 {
5672393Syz155240 	char *s;
5682393Syz155240 	int i;
5692393Syz155240 	int instance;
5702393Syz155240 
5712393Syz155240 #ifdef	IPFDEBUG
5727513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter: ipf_attach(%p,%x)", dip, cmd);
5732393Syz155240 #endif
5742393Syz155240 
5752393Syz155240 	switch (cmd)
5762393Syz155240 	{
5772393Syz155240 	case DDI_ATTACH:
5782393Syz155240 		instance = ddi_get_instance(dip);
5792393Syz155240 		/* Only one instance of ipf (instance 0) can be attached. */
5802393Syz155240 		if (instance > 0)
5817656SSherry.Moore@Sun.COM 			return (DDI_FAILURE);
5822393Syz155240 
5832393Syz155240 #ifdef	IPFDEBUG
5847513SDarren.Reed@Sun.COM 		cmn_err(CE_CONT, "IP Filter: attach ipf instance %d", instance);
5852393Syz155240 #endif
5862393Syz155240 
5873448Sdh155122 		(void) ipf_property_g_update(dip);
5882393Syz155240 
5892393Syz155240 		for (i = 0; ((s = ipf_devfiles[i]) != NULL); i++) {
5902393Syz155240 			s = strrchr(s, '/');
5912393Syz155240 			if (s == NULL)
5922393Syz155240 				continue;
5932393Syz155240 			s++;
5942393Syz155240 			if (ddi_create_minor_node(dip, s, S_IFCHR, i,
5957656SSherry.Moore@Sun.COM 			    DDI_PSEUDO, 0) ==
5962393Syz155240 			    DDI_FAILURE) {
5972393Syz155240 				ddi_remove_minor_node(dip, NULL);
5982393Syz155240 				goto attach_failed;
5992393Syz155240 			}
6002393Syz155240 		}
6012393Syz155240 
6022393Syz155240 		ipf_dev_info = dip;
6037513SDarren.Reed@Sun.COM 
6047513SDarren.Reed@Sun.COM 		ipfncb = net_instance_alloc(NETINFO_VERSION);
6057513SDarren.Reed@Sun.COM 		ipfncb->nin_name = "ipf";
6067513SDarren.Reed@Sun.COM 		ipfncb->nin_create = ipf_stack_create;
6077513SDarren.Reed@Sun.COM 		ipfncb->nin_destroy = ipf_stack_destroy;
6087915SDarren.Reed@Sun.COM 		ipfncb->nin_shutdown = ipf_stack_shutdown;
6097513SDarren.Reed@Sun.COM 		i = net_instance_register(ipfncb);
6107513SDarren.Reed@Sun.COM 
6117513SDarren.Reed@Sun.COM #ifdef IPFDEBUG
6127513SDarren.Reed@Sun.COM 		cmn_err(CE_CONT, "IP Filter:stack_create callback_reg=%d", i);
6137513SDarren.Reed@Sun.COM #endif
6147513SDarren.Reed@Sun.COM 
6157656SSherry.Moore@Sun.COM 		return (DDI_SUCCESS);
6162393Syz155240 		/* NOTREACHED */
6172393Syz155240 	default:
6182393Syz155240 		break;
6192393Syz155240 	}
6202393Syz155240 
6212393Syz155240 attach_failed:
6223448Sdh155122 	ddi_prop_remove_all(dip);
6237656SSherry.Moore@Sun.COM 	return (DDI_FAILURE);
6242393Syz155240 }
6252393Syz155240 
6262393Syz155240 
ipf_detach(dip,cmd)6272393Syz155240 static int ipf_detach(dip, cmd)
6282393Syz155240 dev_info_t *dip;
6292393Syz155240 ddi_detach_cmd_t cmd;
6302393Syz155240 {
6312393Syz155240 	int i;
6322393Syz155240 
6332393Syz155240 #ifdef	IPFDEBUG
6347513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter: ipf_detach(%p,%x)", dip, cmd);
6352393Syz155240 #endif
6362393Syz155240 	switch (cmd) {
6372393Syz155240 	case DDI_DETACH:
6383448Sdh155122 		if (ipf_detach_check_all() != 0)
6397656SSherry.Moore@Sun.COM 			return (DDI_FAILURE);
6402393Syz155240 
6417656SSherry.Moore@Sun.COM 		/*
6427656SSherry.Moore@Sun.COM 		 * Undo what we did in ipf_attach, freeing resources
6432393Syz155240 		 * and removing things we installed.  The system
6442393Syz155240 		 * framework guarantees we are not active with this devinfo
6452393Syz155240 		 * node in any other entry points at this time.
6462393Syz155240 		 */
6472393Syz155240 		ddi_prop_remove_all(dip);
6482393Syz155240 		i = ddi_get_instance(dip);
6492393Syz155240 		ddi_remove_minor_node(dip, NULL);
6502393Syz155240 		if (i > 0) {
6512393Syz155240 			cmn_err(CE_CONT, "IP Filter: still attached (%d)\n", i);
6527656SSherry.Moore@Sun.COM 			return (DDI_FAILURE);
6532393Syz155240 		}
6542393Syz155240 
6557513SDarren.Reed@Sun.COM 		(void) net_instance_unregister(ipfncb);
6567513SDarren.Reed@Sun.COM 		net_instance_free(ipfncb);
6577513SDarren.Reed@Sun.COM 
6587656SSherry.Moore@Sun.COM 		return (DDI_SUCCESS);
6593448Sdh155122 		/* NOTREACHED */
6602393Syz155240 	default:
6612393Syz155240 		break;
6622393Syz155240 	}
6632393Syz155240 	cmn_err(CE_NOTE, "IP Filter: failed to detach\n");
6647656SSherry.Moore@Sun.COM 	return (DDI_FAILURE);
6652393Syz155240 }
6662393Syz155240 
6672393Syz155240 
6682393Syz155240 /*ARGSUSED*/
ipf_getinfo(dip,infocmd,arg,result)6692393Syz155240 static int ipf_getinfo(dip, infocmd, arg, result)
6702393Syz155240 dev_info_t *dip;
6712393Syz155240 ddi_info_cmd_t infocmd;
6722393Syz155240 void *arg, **result;
6732393Syz155240 {
6742393Syz155240 	int error;
6752393Syz155240 
6762393Syz155240 	error = DDI_FAILURE;
6772393Syz155240 #ifdef	IPFDEBUG
6787513SDarren.Reed@Sun.COM 	cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%p,%x,%p)", dip, infocmd, arg);
6792393Syz155240 #endif
6802393Syz155240 	switch (infocmd) {
6812393Syz155240 	case DDI_INFO_DEVT2DEVINFO:
6822393Syz155240 		*result = ipf_dev_info;
6832393Syz155240 		error = DDI_SUCCESS;
6842393Syz155240 		break;
6852393Syz155240 	case DDI_INFO_DEVT2INSTANCE:
6862393Syz155240 		*result = (void *)0;
6872393Syz155240 		error = DDI_SUCCESS;
6882393Syz155240 		break;
6892393Syz155240 	default:
6902393Syz155240 		break;
6912393Syz155240 	}
6922393Syz155240 	return (error);
6932393Syz155240 }
6942393Syz155240 
6952393Syz155240 
6962393Syz155240 /*
6972393Syz155240  * Fetch configuration file values that have been entered into the ipf.conf
6982393Syz155240  * driver file.
6992393Syz155240  */
ipf_property_g_update(dip)7003448Sdh155122 static int ipf_property_g_update(dip)
7012393Syz155240 dev_info_t *dip;
7022393Syz155240 {
7032393Syz155240 #ifdef DDI_NO_AUTODETACH
7042393Syz155240 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
7052393Syz155240 				DDI_NO_AUTODETACH, 1) != DDI_PROP_SUCCESS) {
7062393Syz155240 		cmn_err(CE_WARN, "!updating DDI_NO_AUTODETACH failed");
7077656SSherry.Moore@Sun.COM 		return (DDI_FAILURE);
7082393Syz155240 	}
7092393Syz155240 #else
7102393Syz155240 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
7112393Syz155240 				"ddi-no-autodetach", 1) != DDI_PROP_SUCCESS) {
7122393Syz155240 		cmn_err(CE_WARN, "!updating ddi-no-autodetach failed");
7137656SSherry.Moore@Sun.COM 		return (DDI_FAILURE);
7142393Syz155240 	}
7152393Syz155240 #endif
7162393Syz155240 
7177656SSherry.Moore@Sun.COM 	return (DDI_SUCCESS);
7183448Sdh155122 }
7193448Sdh155122 
7207656SSherry.Moore@Sun.COM int
ipf_property_update(dip,ifs)7217656SSherry.Moore@Sun.COM ipf_property_update(dip, ifs)
7223448Sdh155122 dev_info_t *dip;
7233448Sdh155122 ipf_stack_t *ifs;
7243448Sdh155122 {
7253448Sdh155122 	ipftuneable_t *ipft;
7263448Sdh155122 	char *name;
7277656SSherry.Moore@Sun.COM 	uint_t one;
7283448Sdh155122 	int *i32p;
7297704SAlexandr.Nedvedicky@Sun.COM 	int err, rv = 0;
7302393Syz155240 
7317704SAlexandr.Nedvedicky@Sun.COM 	for (ipft = ifs->ifs_ipf_tuneables;
7327704SAlexandr.Nedvedicky@Sun.COM 		(name = ipft->ipft_name) != NULL; ipft++) {
7337704SAlexandr.Nedvedicky@Sun.COM 		one = 1;
7347704SAlexandr.Nedvedicky@Sun.COM 		i32p = NULL;
7357704SAlexandr.Nedvedicky@Sun.COM 		err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
7367704SAlexandr.Nedvedicky@Sun.COM 						0, name, &i32p, &one);
7377704SAlexandr.Nedvedicky@Sun.COM 		if (err == DDI_PROP_NOT_FOUND)
7387704SAlexandr.Nedvedicky@Sun.COM 			continue;
7397656SSherry.Moore@Sun.COM #ifdef	IPFDEBUG
7407704SAlexandr.Nedvedicky@Sun.COM 		cmn_err(CE_CONT, "IP Filter: lookup_int(%s) = %d\n",
7417704SAlexandr.Nedvedicky@Sun.COM 			name, err);
7427656SSherry.Moore@Sun.COM #endif
7437704SAlexandr.Nedvedicky@Sun.COM 		if (err != DDI_PROP_SUCCESS) {
7447704SAlexandr.Nedvedicky@Sun.COM 			rv = err;
7457704SAlexandr.Nedvedicky@Sun.COM 			continue;
7462393Syz155240 		}
7477704SAlexandr.Nedvedicky@Sun.COM 
7487704SAlexandr.Nedvedicky@Sun.COM 		if (*i32p >= ipft->ipft_min &&
7497704SAlexandr.Nedvedicky@Sun.COM 		    *i32p <= ipft->ipft_max) {
7507704SAlexandr.Nedvedicky@Sun.COM 			if (ipft->ipft_sz == sizeof (uint32_t)) {
7517704SAlexandr.Nedvedicky@Sun.COM 				*ipft->ipft_pint = *i32p;
7527704SAlexandr.Nedvedicky@Sun.COM 			} else if (ipft->ipft_sz == sizeof (uint64_t)) {
7537704SAlexandr.Nedvedicky@Sun.COM 				*ipft->ipft_plong = *i32p;
7547704SAlexandr.Nedvedicky@Sun.COM 			}
7557704SAlexandr.Nedvedicky@Sun.COM 		}
7567704SAlexandr.Nedvedicky@Sun.COM 
7577704SAlexandr.Nedvedicky@Sun.COM 		ddi_prop_free(i32p);
7582393Syz155240 	}
7597704SAlexandr.Nedvedicky@Sun.COM 
7607704SAlexandr.Nedvedicky@Sun.COM 	return (rv);
7612393Syz155240 }
762