xref: /illumos-gate/usr/src/uts/common/inet/ipf/solaris.c (revision 19397407)
1ab25eeb5Syz /*
2ab25eeb5Syz  * Copyright (C) 1993-2001, 2003 by Darren Reed.
3ab25eeb5Syz  *
4ab25eeb5Syz  * See the IPFILTER.LICENCE file for details on licencing.
5ab25eeb5Syz  *
67ddc9b1aSDarren Reed  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
7ab25eeb5Syz  * Use is subject to license terms.
8ab25eeb5Syz  */
9ab25eeb5Syz 
10ab25eeb5Syz #include <sys/systm.h>
11ab25eeb5Syz #include <sys/types.h>
12ab25eeb5Syz #include <sys/param.h>
13ab25eeb5Syz #include <sys/errno.h>
14ab25eeb5Syz #include <sys/uio.h>
15ab25eeb5Syz #include <sys/buf.h>
16ab25eeb5Syz #include <sys/modctl.h>
17ab25eeb5Syz #include <sys/open.h>
18ab25eeb5Syz #include <sys/kmem.h>
19ab25eeb5Syz #include <sys/conf.h>
20ab25eeb5Syz #include <sys/cmn_err.h>
21ab25eeb5Syz #include <sys/stat.h>
22ab25eeb5Syz #include <sys/cred.h>
23ab25eeb5Syz #include <sys/dditypes.h>
24ab25eeb5Syz #include <sys/poll.h>
25ab25eeb5Syz #include <sys/autoconf.h>
26ab25eeb5Syz #include <sys/byteorder.h>
27ab25eeb5Syz #include <sys/socket.h>
28ab25eeb5Syz #include <sys/dlpi.h>
29ab25eeb5Syz #include <sys/stropts.h>
30ab25eeb5Syz #include <sys/kstat.h>
31ab25eeb5Syz #include <sys/sockio.h>
32381a2a9aSdr #include <sys/neti.h>
33381a2a9aSdr #include <sys/hook.h>
34ab25eeb5Syz #include <net/if.h>
35ab25eeb5Syz #if SOLARIS2 >= 6
36*19397407SSherry Moore #include <net/if_types.h>
37ab25eeb5Syz #endif
38ab25eeb5Syz #include <net/af.h>
39ab25eeb5Syz #include <net/route.h>
40ab25eeb5Syz #include <netinet/in.h>
41ab25eeb5Syz #include <netinet/in_systm.h>
42ab25eeb5Syz #include <netinet/if_ether.h>
43ab25eeb5Syz #include <netinet/ip.h>
44ab25eeb5Syz #include <netinet/ip_var.h>
45ab25eeb5Syz #include <netinet/tcp.h>
46ab25eeb5Syz #include <netinet/udp.h>
47ab25eeb5Syz #include <netinet/tcpip.h>
48ab25eeb5Syz #include <netinet/ip_icmp.h>
49ab25eeb5Syz #include <sys/ddi.h>
50ab25eeb5Syz #include <sys/sunddi.h>
51ab25eeb5Syz #include "netinet/ip_compat.h"
52ab25eeb5Syz #include "netinet/ipl.h"
53ab25eeb5Syz #include "netinet/ip_fil.h"
54ab25eeb5Syz #include "netinet/ip_nat.h"
55ab25eeb5Syz #include "netinet/ip_frag.h"
56ab25eeb5Syz #include "netinet/ip_auth.h"
57ab25eeb5Syz #include "netinet/ip_state.h"
58f4b3ec61Sdh #include "netinet/ipf_stack.h"
59ab25eeb5Syz 
60ab25eeb5Syz extern	int	iplwrite __P((dev_t, struct uio *, cred_t *));
61ab25eeb5Syz 
62ab25eeb5Syz static	int	ipf_getinfo __P((dev_info_t *, ddi_info_cmd_t,
63*19397407SSherry Moore 		    void *, void **));
64ab25eeb5Syz #if SOLARIS2 < 10
65ab25eeb5Syz static	int	ipf_identify __P((dev_info_t *));
66ab25eeb5Syz #endif
67ab25eeb5Syz static	int	ipf_attach __P((dev_info_t *, ddi_attach_cmd_t));
68ab25eeb5Syz static	int	ipf_detach __P((dev_info_t *, ddi_detach_cmd_t));
697ddc9b1aSDarren Reed static	void	*ipf_stack_create __P((const netid_t));
707ddc9b1aSDarren Reed static	void	ipf_stack_destroy __P((const netid_t, void *));
71f4b3ec61Sdh static	int	ipf_property_g_update __P((dev_info_t *));
72ab25eeb5Syz static	char	*ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME,
73ab25eeb5Syz 				    IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME,
74ab25eeb5Syz 				    IPLOOKUP_NAME, NULL };
75ab25eeb5Syz 
76ab25eeb5Syz 
77ab25eeb5Syz static struct cb_ops ipf_cb_ops = {
78ab25eeb5Syz 	iplopen,
79ab25eeb5Syz 	iplclose,
80ab25eeb5Syz 	nodev,		/* strategy */
81ab25eeb5Syz 	nodev,		/* print */
82ab25eeb5Syz 	nodev,		/* dump */
83ab25eeb5Syz 	iplread,
84ab25eeb5Syz 	iplwrite,	/* write */
85ab25eeb5Syz 	iplioctl,	/* ioctl */
86ab25eeb5Syz 	nodev,		/* devmap */
87ab25eeb5Syz 	nodev,		/* mmap */
88ab25eeb5Syz 	nodev,		/* segmap */
89ab25eeb5Syz 	nochpoll,	/* poll */
90ab25eeb5Syz 	ddi_prop_op,
91ab25eeb5Syz 	NULL,
92ab25eeb5Syz 	D_MTSAFE,
93ab25eeb5Syz #if SOLARIS2 > 4
94ab25eeb5Syz 	CB_REV,
95ab25eeb5Syz 	nodev,		/* aread */
96ab25eeb5Syz 	nodev,		/* awrite */
97ab25eeb5Syz #endif
98ab25eeb5Syz };
99ab25eeb5Syz 
100ab25eeb5Syz static struct dev_ops ipf_ops = {
101ab25eeb5Syz 	DEVO_REV,
102ab25eeb5Syz 	0,
103ab25eeb5Syz 	ipf_getinfo,
104ab25eeb5Syz #if SOLARIS2 >= 10
105ab25eeb5Syz 	nulldev,
106ab25eeb5Syz #else
107ab25eeb5Syz 	ipf_identify,
108ab25eeb5Syz #endif
109ab25eeb5Syz 	nulldev,
110ab25eeb5Syz 	ipf_attach,
111ab25eeb5Syz 	ipf_detach,
112ab25eeb5Syz 	nodev,		/* reset */
113ab25eeb5Syz 	&ipf_cb_ops,
114*19397407SSherry Moore 	(struct bus_ops *)0,
115*19397407SSherry Moore 	NULL,
116*19397407SSherry Moore 	ddi_quiesce_not_needed,		/* quiesce */
117ab25eeb5Syz };
118ab25eeb5Syz 
1197ddc9b1aSDarren Reed 
1207ddc9b1aSDarren Reed static net_instance_t *ipfncb = NULL;
1217ddc9b1aSDarren Reed static ipf_stack_t *ipf_stacks = NULL;
1227ddc9b1aSDarren Reed static kmutex_t ipf_stack_lock;
123ab25eeb5Syz extern struct mod_ops mod_driverops;
124ab25eeb5Syz static struct modldrv iplmod = {
125ab25eeb5Syz 	&mod_driverops, IPL_VERSION, &ipf_ops };
126ab25eeb5Syz static struct modlinkage modlink1 = { MODREV_1, &iplmod, NULL };
127ab25eeb5Syz 
128ab25eeb5Syz #if SOLARIS2 >= 6
129ab25eeb5Syz static	size_t	hdrsizes[57][2] = {
130ab25eeb5Syz 	{ 0, 0 },
131ab25eeb5Syz 	{ IFT_OTHER, 0 },
132ab25eeb5Syz 	{ IFT_1822, 0 },
133ab25eeb5Syz 	{ IFT_HDH1822, 0 },
134ab25eeb5Syz 	{ IFT_X25DDN, 0 },
135ab25eeb5Syz 	{ IFT_X25, 0 },
136ab25eeb5Syz 	{ IFT_ETHER, 14 },
137ab25eeb5Syz 	{ IFT_ISO88023, 0 },
138ab25eeb5Syz 	{ IFT_ISO88024, 0 },
139ab25eeb5Syz 	{ IFT_ISO88025, 0 },
140ab25eeb5Syz 	{ IFT_ISO88026, 0 },
141ab25eeb5Syz 	{ IFT_STARLAN, 0 },
142ab25eeb5Syz 	{ IFT_P10, 0 },
143ab25eeb5Syz 	{ IFT_P80, 0 },
144ab25eeb5Syz 	{ IFT_HY, 0 },
145ab25eeb5Syz 	{ IFT_FDDI, 24 },
146ab25eeb5Syz 	{ IFT_LAPB, 0 },
147ab25eeb5Syz 	{ IFT_SDLC, 0 },
148ab25eeb5Syz 	{ IFT_T1, 0 },
149ab25eeb5Syz 	{ IFT_CEPT, 0 },
150ab25eeb5Syz 	{ IFT_ISDNBASIC, 0 },
151ab25eeb5Syz 	{ IFT_ISDNPRIMARY, 0 },
152ab25eeb5Syz 	{ IFT_PTPSERIAL, 0 },
153ab25eeb5Syz 	{ IFT_PPP, 0 },
154ab25eeb5Syz 	{ IFT_LOOP, 0 },
155ab25eeb5Syz 	{ IFT_EON, 0 },
156ab25eeb5Syz 	{ IFT_XETHER, 0 },
157ab25eeb5Syz 	{ IFT_NSIP, 0 },
158ab25eeb5Syz 	{ IFT_SLIP, 0 },
159ab25eeb5Syz 	{ IFT_ULTRA, 0 },
160ab25eeb5Syz 	{ IFT_DS3, 0 },
161ab25eeb5Syz 	{ IFT_SIP, 0 },
162ab25eeb5Syz 	{ IFT_FRELAY, 0 },
163ab25eeb5Syz 	{ IFT_RS232, 0 },
164ab25eeb5Syz 	{ IFT_PARA, 0 },
165ab25eeb5Syz 	{ IFT_ARCNET, 0 },
166ab25eeb5Syz 	{ IFT_ARCNETPLUS, 0 },
167ab25eeb5Syz 	{ IFT_ATM, 0 },
168ab25eeb5Syz 	{ IFT_MIOX25, 0 },
169ab25eeb5Syz 	{ IFT_SONET, 0 },
170ab25eeb5Syz 	{ IFT_X25PLE, 0 },
171ab25eeb5Syz 	{ IFT_ISO88022LLC, 0 },
172ab25eeb5Syz 	{ IFT_LOCALTALK, 0 },
173ab25eeb5Syz 	{ IFT_SMDSDXI, 0 },
174ab25eeb5Syz 	{ IFT_FRELAYDCE, 0 },
175ab25eeb5Syz 	{ IFT_V35, 0 },
176ab25eeb5Syz 	{ IFT_HSSI, 0 },
177ab25eeb5Syz 	{ IFT_HIPPI, 0 },
178ab25eeb5Syz 	{ IFT_MODEM, 0 },
179ab25eeb5Syz 	{ IFT_AAL5, 0 },
180ab25eeb5Syz 	{ IFT_SONETPATH, 0 },
181ab25eeb5Syz 	{ IFT_SONETVT, 0 },
182ab25eeb5Syz 	{ IFT_SMDSICIP, 0 },
183ab25eeb5Syz 	{ IFT_PROPVIRTUAL, 0 },
184ab25eeb5Syz 	{ IFT_PROPMUX, 0 },
185ab25eeb5Syz };
186ab25eeb5Syz #endif /* SOLARIS2 >= 6 */
187ab25eeb5Syz 
188f4b3ec61Sdh dev_info_t *ipf_dev_info = NULL;
189ab25eeb5Syz 
190ab25eeb5Syz static const filter_kstats_t ipf_kstat_tmp = {
191ab25eeb5Syz 	{ "pass",			KSTAT_DATA_ULONG },
192ab25eeb5Syz 	{ "block",			KSTAT_DATA_ULONG },
193ab25eeb5Syz 	{ "nomatch",			KSTAT_DATA_ULONG },
194ab25eeb5Syz 	{ "short",			KSTAT_DATA_ULONG },
195ab25eeb5Syz 	{ "pass, logged",		KSTAT_DATA_ULONG },
196ab25eeb5Syz 	{ "block, logged",		KSTAT_DATA_ULONG },
197ab25eeb5Syz 	{ "nomatch, logged",		KSTAT_DATA_ULONG },
198ab25eeb5Syz 	{ "logged",			KSTAT_DATA_ULONG },
199ab25eeb5Syz 	{ "skip",			KSTAT_DATA_ULONG },
200ab25eeb5Syz 	{ "return sent",		KSTAT_DATA_ULONG },
201ab25eeb5Syz 	{ "acct",			KSTAT_DATA_ULONG },
202ab25eeb5Syz 	{ "bad frag state alloc",	KSTAT_DATA_ULONG },
203ab25eeb5Syz 	{ "new frag state kept",	KSTAT_DATA_ULONG },
204ab25eeb5Syz 	{ "new frag state compl. pkt",	KSTAT_DATA_ULONG },
205ab25eeb5Syz 	{ "bad pkt state alloc",	KSTAT_DATA_ULONG },
206ab25eeb5Syz 	{ "new pkt kept state",		KSTAT_DATA_ULONG },
207ab25eeb5Syz 	{ "cachehit",			KSTAT_DATA_ULONG },
208ab25eeb5Syz 	{ "tcp cksum bad",		KSTAT_DATA_ULONG },
209ab25eeb5Syz 	{{ "pullup ok",			KSTAT_DATA_ULONG },
210ab25eeb5Syz 	{ "pullup nok",			KSTAT_DATA_ULONG }},
211ab25eeb5Syz 	{ "src != route",		KSTAT_DATA_ULONG },
212ab25eeb5Syz 	{ "ttl invalid",		KSTAT_DATA_ULONG },
213ab25eeb5Syz 	{ "bad ip pkt",			KSTAT_DATA_ULONG },
214ab25eeb5Syz 	{ "ipv6 pkt",			KSTAT_DATA_ULONG },
215ab25eeb5Syz 	{ "dropped:pps ceiling",	KSTAT_DATA_ULONG },
216ab25eeb5Syz 	{ "ip upd. fail",		KSTAT_DATA_ULONG }
217ab25eeb5Syz };
218ab25eeb5Syz 
219381a2a9aSdr 
220ab25eeb5Syz static int	ipf_kstat_update(kstat_t *ksp, int rwflag);
221ab25eeb5Syz 
222ab25eeb5Syz static void
2237ddc9b1aSDarren Reed ipf_kstat_init(ipf_stack_t *ifs)
224ab25eeb5Syz {
2257ddc9b1aSDarren Reed 	ifs->ifs_kstatp[0] = net_kstat_create(ifs->ifs_netid, "ipf", 0,
2267ddc9b1aSDarren Reed 	    "inbound", "net", KSTAT_TYPE_NAMED,
2277ddc9b1aSDarren Reed 	    sizeof (filter_kstats_t) / sizeof (kstat_named_t), 0);
2287ddc9b1aSDarren Reed 	if (ifs->ifs_kstatp[0] != NULL) {
2297ddc9b1aSDarren Reed 		bcopy(&ipf_kstat_tmp, ifs->ifs_kstatp[0]->ks_data,
2307ddc9b1aSDarren Reed 		    sizeof (filter_kstats_t));
2317ddc9b1aSDarren Reed 		ifs->ifs_kstatp[0]->ks_update = ipf_kstat_update;
2327ddc9b1aSDarren Reed 		ifs->ifs_kstatp[0]->ks_private = &ifs->ifs_frstats[0];
2337ddc9b1aSDarren Reed 		kstat_install(ifs->ifs_kstatp[0]);
2347ddc9b1aSDarren Reed 	}
235ab25eeb5Syz 
2367ddc9b1aSDarren Reed 	ifs->ifs_kstatp[1] = net_kstat_create(ifs->ifs_netid, "ipf", 0,
2377ddc9b1aSDarren Reed 	    "outbound", "net", KSTAT_TYPE_NAMED,
2387ddc9b1aSDarren Reed 	    sizeof (filter_kstats_t) / sizeof (kstat_named_t), 0);
2397ddc9b1aSDarren Reed 	if (ifs->ifs_kstatp[1] != NULL) {
2407ddc9b1aSDarren Reed 		bcopy(&ipf_kstat_tmp, ifs->ifs_kstatp[1]->ks_data,
2417ddc9b1aSDarren Reed 		    sizeof (filter_kstats_t));
2427ddc9b1aSDarren Reed 		ifs->ifs_kstatp[1]->ks_update = ipf_kstat_update;
2437ddc9b1aSDarren Reed 		ifs->ifs_kstatp[1]->ks_private = &ifs->ifs_frstats[1];
2447ddc9b1aSDarren Reed 		kstat_install(ifs->ifs_kstatp[1]);
245ab25eeb5Syz 	}
246ab25eeb5Syz 
247ab25eeb5Syz #ifdef	IPFDEBUG
2487ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter: ipf_kstat_init(%p) installed %p, %p",
249*19397407SSherry Moore 	    ifs, ifs->ifs_kstatp[0], ifs->ifs_kstatp[1]);
250ab25eeb5Syz #endif
251ab25eeb5Syz }
252ab25eeb5Syz 
2537ddc9b1aSDarren Reed 
254ab25eeb5Syz static void
2557ddc9b1aSDarren Reed ipf_kstat_fini(ipf_stack_t *ifs)
256ab25eeb5Syz {
257ab25eeb5Syz 	int i;
258f4b3ec61Sdh 
259ab25eeb5Syz 	for (i = 0; i < 2; i++) {
260f4b3ec61Sdh 		if (ifs->ifs_kstatp[i] != NULL) {
2617ddc9b1aSDarren Reed 			net_kstat_delete(ifs->ifs_netid, ifs->ifs_kstatp[i]);
262f4b3ec61Sdh 			ifs->ifs_kstatp[i] = NULL;
263ab25eeb5Syz 		}
264ab25eeb5Syz 	}
265ab25eeb5Syz }
266ab25eeb5Syz 
2677ddc9b1aSDarren Reed 
268ab25eeb5Syz static int
269ab25eeb5Syz ipf_kstat_update(kstat_t *ksp, int rwflag)
270ab25eeb5Syz {
271ab25eeb5Syz 	filter_kstats_t	*fkp;
272ab25eeb5Syz 	filterstats_t	*fsp;
273ab25eeb5Syz 
274f4b3ec61Sdh 	if (ksp == NULL || ksp->ks_data == NULL)
275f4b3ec61Sdh 		return (EIO);
276f4b3ec61Sdh 
277ab25eeb5Syz 	if (rwflag == KSTAT_WRITE)
278ab25eeb5Syz 		return (EACCES);
279ab25eeb5Syz 
280ab25eeb5Syz 	fkp = ksp->ks_data;
281ab25eeb5Syz 	fsp = ksp->ks_private;
282ab25eeb5Syz 
283ab25eeb5Syz 	fkp->fks_pass.value.ul		= fsp->fr_pass;
284ab25eeb5Syz 	fkp->fks_block.value.ul		= fsp->fr_block;
285ab25eeb5Syz 	fkp->fks_nom.value.ul		= fsp->fr_nom;
286ab25eeb5Syz 	fkp->fks_short.value.ul		= fsp->fr_short;
287ab25eeb5Syz 	fkp->fks_ppkl.value.ul		= fsp->fr_ppkl;
288ab25eeb5Syz 	fkp->fks_bpkl.value.ul		= fsp->fr_bpkl;
289ab25eeb5Syz 	fkp->fks_npkl.value.ul		= fsp->fr_npkl;
290ab25eeb5Syz 	fkp->fks_pkl.value.ul		= fsp->fr_pkl;
291ab25eeb5Syz 	fkp->fks_skip.value.ul		= fsp->fr_skip;
292ab25eeb5Syz 	fkp->fks_ret.value.ul		= fsp->fr_ret;
293ab25eeb5Syz 	fkp->fks_acct.value.ul		= fsp->fr_acct;
294ab25eeb5Syz 	fkp->fks_bnfr.value.ul		= fsp->fr_bnfr;
295ab25eeb5Syz 	fkp->fks_nfr.value.ul		= fsp->fr_nfr;
296ab25eeb5Syz 	fkp->fks_cfr.value.ul		= fsp->fr_cfr;
297ab25eeb5Syz 	fkp->fks_bads.value.ul		= fsp->fr_bads;
298ab25eeb5Syz 	fkp->fks_ads.value.ul		= fsp->fr_ads;
299ab25eeb5Syz 	fkp->fks_chit.value.ul		= fsp->fr_chit;
300ab25eeb5Syz 	fkp->fks_tcpbad.value.ul 	= fsp->fr_tcpbad;
301ab25eeb5Syz 	fkp->fks_pull[0].value.ul 	= fsp->fr_pull[0];
302ab25eeb5Syz 	fkp->fks_pull[1].value.ul 	= fsp->fr_pull[1];
303ab25eeb5Syz 	fkp->fks_badsrc.value.ul 	= fsp->fr_badsrc;
304ab25eeb5Syz 	fkp->fks_badttl.value.ul 	= fsp->fr_badttl;
305ab25eeb5Syz 	fkp->fks_bad.value.ul		= fsp->fr_bad;
306ab25eeb5Syz 	fkp->fks_ipv6.value.ul		= fsp->fr_ipv6;
307ab25eeb5Syz 	fkp->fks_ppshit.value.ul 	= fsp->fr_ppshit;
308ab25eeb5Syz 	fkp->fks_ipud.value.ul		= fsp->fr_ipud;
309ab25eeb5Syz 
310ab25eeb5Syz 	return (0);
311ab25eeb5Syz }
312ab25eeb5Syz 
313*19397407SSherry Moore int
314*19397407SSherry Moore _init()
315ab25eeb5Syz {
316ab25eeb5Syz 	int ipfinst;
317ab25eeb5Syz 
318ab25eeb5Syz 	ipfinst = mod_install(&modlink1);
319ab25eeb5Syz #ifdef	IPFDEBUG
320ab25eeb5Syz 	cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst);
321ab25eeb5Syz #endif
3227ddc9b1aSDarren Reed 	mutex_init(&ipf_stack_lock, NULL, MUTEX_DRIVER, NULL);
323*19397407SSherry Moore 	return (ipfinst);
324ab25eeb5Syz }
325ab25eeb5Syz 
326ab25eeb5Syz 
327*19397407SSherry Moore int
328*19397407SSherry Moore _fini(void)
329ab25eeb5Syz {
330ab25eeb5Syz 	int ipfinst;
331ab25eeb5Syz 
332ab25eeb5Syz 	ipfinst = mod_remove(&modlink1);
333ab25eeb5Syz #ifdef	IPFDEBUG
334ab25eeb5Syz 	cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst);
335ab25eeb5Syz #endif
336*19397407SSherry Moore 	return (ipfinst);
337ab25eeb5Syz }
338ab25eeb5Syz 
339ab25eeb5Syz 
340*19397407SSherry Moore int
341*19397407SSherry Moore _info(modinfop)
342ab25eeb5Syz struct modinfo *modinfop;
343ab25eeb5Syz {
344ab25eeb5Syz 	int ipfinst;
345ab25eeb5Syz 
346ab25eeb5Syz 	ipfinst = mod_info(&modlink1, modinfop);
347ab25eeb5Syz #ifdef	IPFDEBUG
3487ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter: _info(%p) = %d", modinfop, ipfinst);
349ab25eeb5Syz #endif
350*19397407SSherry Moore 	return (ipfinst);
351ab25eeb5Syz }
352ab25eeb5Syz 
353ab25eeb5Syz 
354ab25eeb5Syz #if SOLARIS2 < 10
355ab25eeb5Syz static int ipf_identify(dip)
356ab25eeb5Syz dev_info_t *dip;
357ab25eeb5Syz {
358*19397407SSherry Moore #ifdef	IPFDEBUG
3597ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter: ipf_identify(%p)", dip);
360*19397407SSherry Moore #endif
361ab25eeb5Syz 	if (strcmp(ddi_get_name(dip), "ipf") == 0)
362ab25eeb5Syz 		return (DDI_IDENTIFIED);
363ab25eeb5Syz 	return (DDI_NOT_IDENTIFIED);
364ab25eeb5Syz }
365ab25eeb5Syz #endif
366ab25eeb5Syz 
367f4b3ec61Sdh /*
368f4b3ec61Sdh  * Initialize things for IPF for each stack instance
369f4b3ec61Sdh  */
370f4b3ec61Sdh static void *
3717ddc9b1aSDarren Reed ipf_stack_create(const netid_t id)
372f4b3ec61Sdh {
373f4b3ec61Sdh 	ipf_stack_t	*ifs;
374f4b3ec61Sdh 
3757ddc9b1aSDarren Reed #ifdef IPFDEBUG
3767ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter:stack_create id=%d", id);
377f4b3ec61Sdh #endif
378f4b3ec61Sdh 
3797ddc9b1aSDarren Reed 	ifs = (ipf_stack_t *)kmem_alloc(sizeof (*ifs), KM_SLEEP);
380f4b3ec61Sdh 	bzero(ifs, sizeof (*ifs));
381f4b3ec61Sdh 
382f4b3ec61Sdh 	ifs->ifs_hook4_physical_in	= B_FALSE;
383f4b3ec61Sdh 	ifs->ifs_hook4_physical_out	= B_FALSE;
384f4b3ec61Sdh 	ifs->ifs_hook4_nic_events	= B_FALSE;
385f4b3ec61Sdh 	ifs->ifs_hook4_loopback_in	= B_FALSE;
386f4b3ec61Sdh 	ifs->ifs_hook4_loopback_out	= B_FALSE;
387f4b3ec61Sdh 	ifs->ifs_hook6_physical_in	= B_FALSE;
388f4b3ec61Sdh 	ifs->ifs_hook6_physical_out	= B_FALSE;
389f4b3ec61Sdh 	ifs->ifs_hook6_nic_events	= B_FALSE;
390f4b3ec61Sdh 	ifs->ifs_hook6_loopback_in	= B_FALSE;
391f4b3ec61Sdh 	ifs->ifs_hook6_loopback_out	= B_FALSE;
392f4b3ec61Sdh 
393f4b3ec61Sdh 	/*
394f4b3ec61Sdh 	 * Initialize mutex's
395f4b3ec61Sdh 	 */
396f4b3ec61Sdh 	RWLOCK_INIT(&ifs->ifs_ipf_global, "ipf filter load/unload mutex");
397f4b3ec61Sdh 	RWLOCK_INIT(&ifs->ifs_ipf_mutex, "ipf filter rwlock");
3987ddc9b1aSDarren Reed 
3997ddc9b1aSDarren Reed 	ifs->ifs_netid = id;
4007ddc9b1aSDarren Reed 	ifs->ifs_zone = net_getzoneidbynetid(id);
4017ddc9b1aSDarren Reed 	ipf_kstat_init(ifs);
4027ddc9b1aSDarren Reed 
4037ddc9b1aSDarren Reed #ifdef IPFDEBUG
4047ddc9b1aSDarren Reed 	cmn_err(CE_CONT, "IP Filter:stack_create zone=%d", ifs->ifs_zone);
405f4b3ec61Sdh #endif
406f4b3ec61Sdh 
407f4b3ec61Sdh 	/*
408f4b3ec61Sdh 	 * Lock people out while we set things up.
409f4b3ec61Sdh 	 */
410f4b3ec61Sdh 	WRITE_ENTER(&ifs->ifs_ipf_global);
411f4b3ec61Sdh 	ipftuneable_alloc(ifs);
412f4b3ec61Sdh 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
413f4b3ec61Sdh 
41423f4867fSnordmark 	/* Limit to global stack */
4157ddc9b1aSDarren Reed 	if (ifs->ifs_zone == GLOBAL_ZONEID)
41623f4867fSnordmark 		cmn_err(CE_CONT, "!%s, running.\n", ipfilter_version);
41723f4867fSnordmark 
4187ddc9b1aSDarren Reed 	mutex_enter(&ipf_stack_lock);
4197ddc9b1aSDarren Reed 	if (ipf_stacks != NULL)
4207ddc9b1aSDarren Reed 		ipf_stacks->ifs_pnext = &ifs->ifs_next;
4217ddc9b1aSDarren Reed 	ifs->ifs_next = ipf_stacks;
4227ddc9b1aSDarren Reed 	ifs->ifs_pnext = &ipf_stacks;
4237ddc9b1aSDarren Reed 	ipf_stacks = ifs;
4247ddc9b1aSDarren Reed 	mutex_exit(&ipf_stack_lock);
4257ddc9b1aSDarren Reed 
426f4b3ec61Sdh 	return (ifs);
427f4b3ec61Sdh }
428f4b3ec61Sdh 
4297ddc9b1aSDarren Reed 
4307ddc9b1aSDarren Reed /*
4317ddc9b1aSDarren Reed  * This function should only ever be used to find the pointer to the
4327ddc9b1aSDarren Reed  * ipfilter stack structure for the zone that is currently being
4337ddc9b1aSDarren Reed  * executed... so if you're running in the context of zone 1, you
4347ddc9b1aSDarren Reed  * should not attempt to find the ipf_stack_t for zone 0 or 2 or
4357ddc9b1aSDarren Reed  * anything else but 1.  In that way, the returned pointer is safe
4367ddc9b1aSDarren Reed  * as it will only be nuked when the instance is destroyed as part
4377ddc9b1aSDarren Reed  * of the final shutdown of a zone.
4387ddc9b1aSDarren Reed  */
439*19397407SSherry Moore ipf_stack_t *
440*19397407SSherry Moore ipf_find_stack(const zoneid_t zone)
4417ddc9b1aSDarren Reed {
4427ddc9b1aSDarren Reed 	ipf_stack_t *ifs;
4437ddc9b1aSDarren Reed 
4447ddc9b1aSDarren Reed 	mutex_enter(&ipf_stack_lock);
4457ddc9b1aSDarren Reed 	for (ifs = ipf_stacks; ifs != NULL; ifs = ifs->ifs_next) {
4467ddc9b1aSDarren Reed 		if (ifs->ifs_zone == zone)
4477ddc9b1aSDarren Reed 			break;
4487ddc9b1aSDarren Reed 	}
4497ddc9b1aSDarren Reed 	mutex_exit(&ipf_stack_lock);
450*19397407SSherry Moore 	return (ifs);
4517ddc9b1aSDarren Reed }
4527ddc9b1aSDarren Reed 
4537ddc9b1aSDarren Reed 
454f4b3ec61Sdh static int ipf_detach_check_zone(ipf_stack_t *ifs)
455f4b3ec61Sdh {
456f4b3ec61Sdh 	/*
457f4b3ec61Sdh 	 * Make sure we're the only one's modifying things.  With
458f4b3ec61Sdh 	 * this lock others should just fall out of the loop.
459f4b3ec61Sdh 	 */
460f4b3ec61Sdh 	READ_ENTER(&ifs->ifs_ipf_global);
461f4b3ec61Sdh 	if (ifs->ifs_fr_running == 1) {
462f4b3ec61Sdh 		RWLOCK_EXIT(&ifs->ifs_ipf_global);
463f4b3ec61Sdh 		return (-1);
464f4b3ec61Sdh 	}
465*19397407SSherry Moore 
466f4b3ec61Sdh 	/*
467f4b3ec61Sdh 	 * Make sure there is no active filter rule.
468f4b3ec61Sdh 	 */
469f4b3ec61Sdh 	if (ifs->ifs_ipfilter[0][ifs->ifs_fr_active] ||
470f4b3ec61Sdh 	    ifs->ifs_ipfilter[1][ifs->ifs_fr_active] ||
471f4b3ec61Sdh 	    ifs->ifs_ipfilter6[0][ifs->ifs_fr_active] ||
472f4b3ec61Sdh 	    ifs->ifs_ipfilter6[1][ifs->ifs_fr_active]) {
473f4b3ec61Sdh 		RWLOCK_EXIT(&ifs->ifs_ipf_global);
474f4b3ec61Sdh 		return (-1);
475f4b3ec61Sdh 	}
476f4b3ec61Sdh 
477f4b3ec61Sdh 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
478f4b3ec61Sdh 
479f4b3ec61Sdh 	return (0);
480f4b3ec61Sdh }
481f4b3ec61Sdh 
4827ddc9b1aSDarren Reed 
483f4b3ec61Sdh static int ipf_detach_check_all()
484f4b3ec61Sdh {
4857ddc9b1aSDarren Reed 	ipf_stack_t *ifs;
4867ddc9b1aSDarren Reed 
4877ddc9b1aSDarren Reed 	mutex_enter(&ipf_stack_lock);
4887ddc9b1aSDarren Reed 	for (ifs = ipf_stacks; ifs != NULL; ifs = ifs->ifs_next)
4897ddc9b1aSDarren Reed 		if (ipf_detach_check_zone(ifs) != 0)
4907ddc9b1aSDarren Reed 			break;
4917ddc9b1aSDarren Reed 	mutex_exit(&ipf_stack_lock);
4927ddc9b1aSDarren Reed 	return ((ifs == NULL) ? 0 : -1);
493f4b3ec61Sdh }
494f4b3ec61Sdh 
4957ddc9b1aSDarren Reed 
496f4b3ec61Sdh /*
497f4b3ec61Sdh  * Destroy things for ipf for one stack.
498f4b3ec61Sdh  */
499f4b3ec61Sdh /* ARGSUSED */
500f4b3ec61Sdh static void
5017ddc9b1aSDarren Reed ipf_stack_destroy(const netid_t id, void *arg)
502f4b3ec61Sdh {
503f4b3ec61Sdh 	ipf_stack_t *ifs = (ipf_stack_t *)arg;
5047ddc9b1aSDarren Reed 	timeout_id_t tid;
505f4b3ec61Sdh 
5067ddc9b1aSDarren Reed #ifdef IPFDEBUG
5077ddc9b1aSDarren Reed 	(void) printf("ipf_stack_destroy(%p)\n", (void *)ifs);
508f4b3ec61Sdh #endif
509f4b3ec61Sdh 
510f4b3ec61Sdh 	/*
511f4b3ec61Sdh 	 * Make sure we're the only one's modifying things.  With
512f4b3ec61Sdh 	 * this lock others should just fall out of the loop.
513f4b3ec61Sdh 	 */
514f4b3ec61Sdh 	WRITE_ENTER(&ifs->ifs_ipf_global);
515f4b3ec61Sdh 	if (ifs->ifs_fr_running == -2) {
516f4b3ec61Sdh 		RWLOCK_EXIT(&ifs->ifs_ipf_global);
517f4b3ec61Sdh 		return;
518f4b3ec61Sdh 	}
519f4b3ec61Sdh 	ifs->ifs_fr_running = -2;
5207ddc9b1aSDarren Reed 	tid = ifs->ifs_fr_timer_id;
5217ddc9b1aSDarren Reed 	ifs->ifs_fr_timer_id = NULL;
522f4b3ec61Sdh 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
523f4b3ec61Sdh 
5247ddc9b1aSDarren Reed 	mutex_enter(&ipf_stack_lock);
5257ddc9b1aSDarren Reed 	if (ifs->ifs_next != NULL)
5267ddc9b1aSDarren Reed 		ifs->ifs_next->ifs_pnext = ifs->ifs_pnext;
5277ddc9b1aSDarren Reed 	*ifs->ifs_pnext = ifs->ifs_next;
5287ddc9b1aSDarren Reed 	mutex_exit(&ipf_stack_lock);
5297ddc9b1aSDarren Reed 
5307ddc9b1aSDarren Reed 	ipf_kstat_fini(ifs);
5317ddc9b1aSDarren Reed 
5327ddc9b1aSDarren Reed 	if (tid != NULL)
5337ddc9b1aSDarren Reed 		(void) untimeout(tid);
534f4b3ec61Sdh 
535f4b3ec61Sdh 	WRITE_ENTER(&ifs->ifs_ipf_global);
536f4b3ec61Sdh 	if (ipldetach(ifs) != 0) {
5377ddc9b1aSDarren Reed 		printf("ipf_stack_destroy: ipldetach failed\n");
538f4b3ec61Sdh 	}
539f4b3ec61Sdh 
540f4b3ec61Sdh 	ipftuneable_free(ifs);
541f4b3ec61Sdh 
542f4b3ec61Sdh 	RWLOCK_EXIT(&ifs->ifs_ipf_global);
543f4b3ec61Sdh 	RW_DESTROY(&ifs->ifs_ipf_mutex);
544f4b3ec61Sdh 	RW_DESTROY(&ifs->ifs_ipf_global);
545f4b3ec61Sdh 
546f4b3ec61Sdh 	KFREE(ifs);
547f4b3ec61Sdh }
548ab25eeb5Syz 
5497ddc9b1aSDarren Reed 
550ab25eeb5Syz static int ipf_attach(dip, cmd)
551ab25eeb5Syz dev_info_t *dip;
552ab25eeb5Syz ddi_attach_cmd_t cmd;
553ab25eeb5Syz {
554ab25eeb5Syz 	char *s;
555ab25eeb5Syz 	int i;
556ab25eeb5Syz 	int instance;
557ab25eeb5Syz 
558ab25eeb5Syz #ifdef	IPFDEBUG
5597ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter: ipf_attach(%p,%x)", dip, cmd);
560ab25eeb5Syz #endif
561ab25eeb5Syz 
562ab25eeb5Syz 	switch (cmd)
563ab25eeb5Syz 	{
564ab25eeb5Syz 	case DDI_ATTACH:
565ab25eeb5Syz 		instance = ddi_get_instance(dip);
566ab25eeb5Syz 		/* Only one instance of ipf (instance 0) can be attached. */
567ab25eeb5Syz 		if (instance > 0)
568*19397407SSherry Moore 			return (DDI_FAILURE);
569ab25eeb5Syz 
570ab25eeb5Syz #ifdef	IPFDEBUG
5717ddc9b1aSDarren Reed 		cmn_err(CE_CONT, "IP Filter: attach ipf instance %d", instance);
572ab25eeb5Syz #endif
573ab25eeb5Syz 
574f4b3ec61Sdh 		(void) ipf_property_g_update(dip);
575ab25eeb5Syz 
576ab25eeb5Syz 		for (i = 0; ((s = ipf_devfiles[i]) != NULL); i++) {
577ab25eeb5Syz 			s = strrchr(s, '/');
578ab25eeb5Syz 			if (s == NULL)
579ab25eeb5Syz 				continue;
580ab25eeb5Syz 			s++;
581ab25eeb5Syz 			if (ddi_create_minor_node(dip, s, S_IFCHR, i,
582*19397407SSherry Moore 			    DDI_PSEUDO, 0) ==
583ab25eeb5Syz 			    DDI_FAILURE) {
584ab25eeb5Syz 				ddi_remove_minor_node(dip, NULL);
585ab25eeb5Syz 				goto attach_failed;
586ab25eeb5Syz 			}
587ab25eeb5Syz 		}
588ab25eeb5Syz 
589ab25eeb5Syz 		ipf_dev_info = dip;
5907ddc9b1aSDarren Reed 
5917ddc9b1aSDarren Reed 		ipfncb = net_instance_alloc(NETINFO_VERSION);
5927ddc9b1aSDarren Reed 		ipfncb->nin_name = "ipf";
5937ddc9b1aSDarren Reed 		ipfncb->nin_create = ipf_stack_create;
5947ddc9b1aSDarren Reed 		ipfncb->nin_destroy = ipf_stack_destroy;
5957ddc9b1aSDarren Reed 		ipfncb->nin_shutdown = NULL;
5967ddc9b1aSDarren Reed 		i = net_instance_register(ipfncb);
5977ddc9b1aSDarren Reed 
5987ddc9b1aSDarren Reed #ifdef IPFDEBUG
5997ddc9b1aSDarren Reed 		cmn_err(CE_CONT, "IP Filter:stack_create callback_reg=%d", i);
6007ddc9b1aSDarren Reed #endif
6017ddc9b1aSDarren Reed 
602*19397407SSherry Moore 		return (DDI_SUCCESS);
603ab25eeb5Syz 		/* NOTREACHED */
604ab25eeb5Syz 	default:
605ab25eeb5Syz 		break;
606ab25eeb5Syz 	}
607ab25eeb5Syz 
608ab25eeb5Syz attach_failed:
609f4b3ec61Sdh 	ddi_prop_remove_all(dip);
610*19397407SSherry Moore 	return (DDI_FAILURE);
611ab25eeb5Syz }
612ab25eeb5Syz 
613ab25eeb5Syz 
614ab25eeb5Syz static int ipf_detach(dip, cmd)
615ab25eeb5Syz dev_info_t *dip;
616ab25eeb5Syz ddi_detach_cmd_t cmd;
617ab25eeb5Syz {
618ab25eeb5Syz 	int i;
619ab25eeb5Syz 
620ab25eeb5Syz #ifdef	IPFDEBUG
6217ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter: ipf_detach(%p,%x)", dip, cmd);
622ab25eeb5Syz #endif
623ab25eeb5Syz 	switch (cmd) {
624ab25eeb5Syz 	case DDI_DETACH:
625f4b3ec61Sdh 		if (ipf_detach_check_all() != 0)
626*19397407SSherry Moore 			return (DDI_FAILURE);
627ab25eeb5Syz 
628*19397407SSherry Moore 		/*
629*19397407SSherry Moore 		 * Undo what we did in ipf_attach, freeing resources
630ab25eeb5Syz 		 * and removing things we installed.  The system
631ab25eeb5Syz 		 * framework guarantees we are not active with this devinfo
632ab25eeb5Syz 		 * node in any other entry points at this time.
633ab25eeb5Syz 		 */
634ab25eeb5Syz 		ddi_prop_remove_all(dip);
635ab25eeb5Syz 		i = ddi_get_instance(dip);
636ab25eeb5Syz 		ddi_remove_minor_node(dip, NULL);
637ab25eeb5Syz 		if (i > 0) {
638ab25eeb5Syz 			cmn_err(CE_CONT, "IP Filter: still attached (%d)\n", i);
639*19397407SSherry Moore 			return (DDI_FAILURE);
640ab25eeb5Syz 		}
641ab25eeb5Syz 
6427ddc9b1aSDarren Reed 		(void) net_instance_unregister(ipfncb);
6437ddc9b1aSDarren Reed 		net_instance_free(ipfncb);
6447ddc9b1aSDarren Reed 
645*19397407SSherry Moore 		return (DDI_SUCCESS);
646f4b3ec61Sdh 		/* NOTREACHED */
647ab25eeb5Syz 	default:
648ab25eeb5Syz 		break;
649ab25eeb5Syz 	}
650ab25eeb5Syz 	cmn_err(CE_NOTE, "IP Filter: failed to detach\n");
651*19397407SSherry Moore 	return (DDI_FAILURE);
652ab25eeb5Syz }
653ab25eeb5Syz 
654ab25eeb5Syz 
655ab25eeb5Syz /*ARGSUSED*/
656ab25eeb5Syz static int ipf_getinfo(dip, infocmd, arg, result)
657ab25eeb5Syz dev_info_t *dip;
658ab25eeb5Syz ddi_info_cmd_t infocmd;
659ab25eeb5Syz void *arg, **result;
660ab25eeb5Syz {
661ab25eeb5Syz 	int error;
662ab25eeb5Syz 
663ab25eeb5Syz 	error = DDI_FAILURE;
664ab25eeb5Syz #ifdef	IPFDEBUG
6657ddc9b1aSDarren Reed 	cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%p,%x,%p)", dip, infocmd, arg);
666ab25eeb5Syz #endif
667ab25eeb5Syz 	switch (infocmd) {
668ab25eeb5Syz 	case DDI_INFO_DEVT2DEVINFO:
669ab25eeb5Syz 		*result = ipf_dev_info;
670ab25eeb5Syz 		error = DDI_SUCCESS;
671ab25eeb5Syz 		break;
672ab25eeb5Syz 	case DDI_INFO_DEVT2INSTANCE:
673ab25eeb5Syz 		*result = (void *)0;
674ab25eeb5Syz 		error = DDI_SUCCESS;
675ab25eeb5Syz 		break;
676ab25eeb5Syz 	default:
677ab25eeb5Syz 		break;
678ab25eeb5Syz 	}
679ab25eeb5Syz 	return (error);
680ab25eeb5Syz }
681ab25eeb5Syz 
682ab25eeb5Syz 
683ab25eeb5Syz /*
684ab25eeb5Syz  * Fetch configuration file values that have been entered into the ipf.conf
685ab25eeb5Syz  * driver file.
686ab25eeb5Syz  */
687f4b3ec61Sdh static int ipf_property_g_update(dip)
688ab25eeb5Syz dev_info_t *dip;
689ab25eeb5Syz {
690ab25eeb5Syz #ifdef DDI_NO_AUTODETACH
691ab25eeb5Syz 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
692ab25eeb5Syz 				DDI_NO_AUTODETACH, 1) != DDI_PROP_SUCCESS) {
693ab25eeb5Syz 		cmn_err(CE_WARN, "!updating DDI_NO_AUTODETACH failed");
694*19397407SSherry Moore 		return (DDI_FAILURE);
695ab25eeb5Syz 	}
696ab25eeb5Syz #else
697ab25eeb5Syz 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
698ab25eeb5Syz 				"ddi-no-autodetach", 1) != DDI_PROP_SUCCESS) {
699ab25eeb5Syz 		cmn_err(CE_WARN, "!updating ddi-no-autodetach failed");
700*19397407SSherry Moore 		return (DDI_FAILURE);
701ab25eeb5Syz 	}
702ab25eeb5Syz #endif
703ab25eeb5Syz 
704*19397407SSherry Moore 	return (DDI_SUCCESS);
705f4b3ec61Sdh }
706f4b3ec61Sdh 
707*19397407SSherry Moore int
708*19397407SSherry Moore ipf_property_update(dip, ifs)
709f4b3ec61Sdh dev_info_t *dip;
710f4b3ec61Sdh ipf_stack_t *ifs;
711f4b3ec61Sdh {
712f4b3ec61Sdh 	ipftuneable_t *ipft;
713f4b3ec61Sdh 	int64_t *i64p;
714f4b3ec61Sdh 	char *name;
715*19397407SSherry Moore 	uint_t one;
716f4b3ec61Sdh 	int *i32p;
717f4b3ec61Sdh 	int err;
718f4b3ec61Sdh 
719*19397407SSherry Moore 	for (ipft = ifs->ifs_ipf_tuneables; (name = ipft->ipft_name) != NULL;
720*19397407SSherry Moore 	ipft++) {
721ab25eeb5Syz 		one = 1;
722ab25eeb5Syz 		switch (ipft->ipft_sz)
723ab25eeb5Syz 		{
724ab25eeb5Syz 		case 4 :
725ab25eeb5Syz 			i32p = NULL;
726ab25eeb5Syz 			err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
727ab25eeb5Syz 							0, name, &i32p, &one);
728ab25eeb5Syz 			if (err == DDI_PROP_NOT_FOUND)
729ab25eeb5Syz 				continue;
730ab25eeb5Syz #ifdef	IPFDEBUG
731ab25eeb5Syz 			cmn_err(CE_CONT, "IP Filter: lookup_int(%s) = %d\n",
732ab25eeb5Syz 				name, err);
733ab25eeb5Syz #endif
734ab25eeb5Syz 			if (err != DDI_PROP_SUCCESS)
735*19397407SSherry Moore 				return (err);
736ab25eeb5Syz 			if (*i32p >= ipft->ipft_min && *i32p <= ipft->ipft_max)
737ab25eeb5Syz 				*ipft->ipft_pint = *i32p;
738ab25eeb5Syz 			else
739ab25eeb5Syz 				err = DDI_PROP_CANNOT_DECODE;
740ab25eeb5Syz 			ddi_prop_free(i32p);
741ab25eeb5Syz 			break;
742ab25eeb5Syz 
743ab25eeb5Syz #if SOLARIS2 > 8
744ab25eeb5Syz 		case 8 :
745ab25eeb5Syz 			i64p = NULL;
746ab25eeb5Syz 			err = ddi_prop_lookup_int64_array(DDI_DEV_T_ANY, dip,
747*19397407SSherry Moore 			    0, name, &i64p, &one);
748ab25eeb5Syz 			if (err == DDI_PROP_NOT_FOUND)
749ab25eeb5Syz 				continue;
750*19397407SSherry Moore #ifdef	IPFDEBUG
751ab25eeb5Syz 			cmn_err(CE_CONT, "IP Filter: lookup_int64(%s) = %d\n",
752*19397407SSherry Moore 			    name, err);
753*19397407SSherry Moore #endif
754ab25eeb5Syz 			if (err != DDI_PROP_SUCCESS)
755*19397407SSherry Moore 				return (err);
756ab25eeb5Syz 			if (*i64p >= ipft->ipft_min && *i64p <= ipft->ipft_max)
757ab25eeb5Syz 				*ipft->ipft_pint = *i64p;
758ab25eeb5Syz 			else
759ab25eeb5Syz 				err = DDI_PROP_CANNOT_DECODE;
760ab25eeb5Syz 			ddi_prop_free(i64p);
761ab25eeb5Syz 			break;
762ab25eeb5Syz #endif
763ab25eeb5Syz 		default :
764ab25eeb5Syz 			break;
765ab25eeb5Syz 		}
766ab25eeb5Syz 		if (err != DDI_SUCCESS)
767ab25eeb5Syz 			break;
768ab25eeb5Syz 	}
769*19397407SSherry Moore 	return (err);
770ab25eeb5Syz }
771