xref: /onnv-gate/usr/src/uts/common/inet/ipf/ip_lookup.c (revision 7433:bad57c69bd98)
12393Syz155240 /*
22393Syz155240  * Copyright (C) 2002-2003 by Darren Reed.
32393Syz155240  *
42393Syz155240  * See the IPFILTER.LICENCE file for details on licencing.
52393Syz155240  *
6*7433SJohn.Ojemann@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
72393Syz155240  * Use is subject to license terms.
82393Syz155240  */
92393Syz155240 
102393Syz155240 #if defined(KERNEL) || defined(_KERNEL)
112393Syz155240 # undef KERNEL
122393Syz155240 # undef _KERNEL
132393Syz155240 # define        KERNEL	1
142393Syz155240 # define        _KERNEL	1
152393Syz155240 #endif
162393Syz155240 #if defined(__osf__)
172393Syz155240 # define _PROTO_NET_H_
182393Syz155240 #endif
192393Syz155240 #include <sys/param.h>
202393Syz155240 #include <sys/errno.h>
212393Syz155240 #include <sys/types.h>
222393Syz155240 #include <sys/time.h>
232393Syz155240 #include <sys/file.h>
242393Syz155240 #if __FreeBSD_version >= 220000 && defined(_KERNEL)
252393Syz155240 # include <sys/fcntl.h>
262393Syz155240 # include <sys/filio.h>
272393Syz155240 #else
282393Syz155240 # include <sys/ioctl.h>
292393Syz155240 #endif
302393Syz155240 #if !defined(_KERNEL)
312393Syz155240 # include <string.h>
322393Syz155240 # define _KERNEL
332393Syz155240 # ifdef __OpenBSD__
342393Syz155240 struct file;
352393Syz155240 # endif
362393Syz155240 # include <sys/uio.h>
372393Syz155240 # undef _KERNEL
382393Syz155240 #endif
392393Syz155240 #include <sys/socket.h>
402393Syz155240 #if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
412393Syz155240 # ifdef __osf__
422393Syz155240 #  include <net/radix.h>
432393Syz155240 # endif
442393Syz155240 # include "radix_ipf_local.h"
452393Syz155240 # define _RADIX_H_
462393Syz155240 #endif
472393Syz155240 #include <net/if.h>
482393Syz155240 #if defined(__FreeBSD__)
492393Syz155240 #  include <sys/cdefs.h>
502393Syz155240 #  include <sys/proc.h>
512393Syz155240 #endif
522393Syz155240 #if defined(_KERNEL)
532393Syz155240 # include <sys/systm.h>
542393Syz155240 # if !defined(__SVR4) && !defined(__svr4__)
552393Syz155240 #  include <sys/mbuf.h>
562393Syz155240 # endif
572393Syz155240 #endif
582393Syz155240 #include <netinet/in.h>
592393Syz155240 
602393Syz155240 #include "netinet/ip_compat.h"
612393Syz155240 #include "netinet/ip_fil.h"
622393Syz155240 #include "netinet/ip_pool.h"
632393Syz155240 #include "netinet/ip_htable.h"
642393Syz155240 #include "netinet/ip_lookup.h"
653448Sdh155122 #include "netinet/ipf_stack.h"
662393Syz155240 /* END OF INCLUDES */
672393Syz155240 
682393Syz155240 #if !defined(lint)
692393Syz155240 static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.7 2005/06/12 07:18:20 darrenr Exp $";
702393Syz155240 #endif
712393Syz155240 
722393Syz155240 #ifdef	IPFILTER_LOOKUP
733448Sdh155122 static int iplookup_addnode __P((caddr_t, ipf_stack_t *));
743448Sdh155122 static int iplookup_delnode __P((caddr_t data, ipf_stack_t *));
753448Sdh155122 static int iplookup_addtable __P((caddr_t, ipf_stack_t *));
763448Sdh155122 static int iplookup_deltable __P((caddr_t, ipf_stack_t *));
773448Sdh155122 static int iplookup_stats __P((caddr_t, ipf_stack_t *));
783448Sdh155122 static int iplookup_flush __P((caddr_t, ipf_stack_t *));
792393Syz155240 
802393Syz155240 
812393Syz155240 
822393Syz155240 /* ------------------------------------------------------------------------ */
832393Syz155240 /* Function:    iplookup_init                                               */
842393Syz155240 /* Returns:     int     - 0 = success, else error                           */
852393Syz155240 /* Parameters:  Nil                                                         */
862393Syz155240 /*                                                                          */
872393Syz155240 /* Initialise all of the subcomponents of the lookup infrstructure.         */
882393Syz155240 /* ------------------------------------------------------------------------ */
ip_lookup_init(ifs)893448Sdh155122 int ip_lookup_init(ifs)
903448Sdh155122 ipf_stack_t *ifs;
912393Syz155240 {
922393Syz155240 
933448Sdh155122 	if (ip_pool_init(ifs) == -1)
942393Syz155240 		return -1;
952393Syz155240 
963448Sdh155122 	RWLOCK_INIT(&ifs->ifs_ip_poolrw, "ip pool rwlock");
972393Syz155240 
983448Sdh155122 	ifs->ifs_ip_lookup_inited = 1;
993448Sdh155122 	ifs->ifs_ipftokenhead = NULL;
1003448Sdh155122 	ifs->ifs_ipftokentail = &ifs->ifs_ipftokenhead;
1012393Syz155240 	return 0;
1022393Syz155240 }
1032393Syz155240 
1042393Syz155240 
1052393Syz155240 /* ------------------------------------------------------------------------ */
1062393Syz155240 /* Function:    iplookup_unload                                             */
1072393Syz155240 /* Returns:     int     - 0 = success, else error                           */
1082393Syz155240 /* Parameters:  Nil                                                         */
1092393Syz155240 /*                                                                          */
1102393Syz155240 /* Free up all pool related memory that has been allocated whilst IPFilter  */
1112393Syz155240 /* has been running.  Also, do any other deinitialisation required such     */
1122393Syz155240 /* ip_lookup_init() can be called again, safely.                            */
1132393Syz155240 /* ------------------------------------------------------------------------ */
ip_lookup_unload(ifs)1143448Sdh155122 void ip_lookup_unload(ifs)
1153448Sdh155122 ipf_stack_t *ifs;
1162393Syz155240 {
1173448Sdh155122 	ip_pool_fini(ifs);
1183448Sdh155122 	fr_htable_unload(ifs);
1192393Syz155240 
1203448Sdh155122 	if (ifs->ifs_ip_lookup_inited == 1) {
1213448Sdh155122 		RW_DESTROY(&ifs->ifs_ip_poolrw);
1223448Sdh155122 		ifs->ifs_ip_lookup_inited = 0;
1232393Syz155240 	}
1242393Syz155240 }
1252393Syz155240 
1262393Syz155240 
1272393Syz155240 /* ------------------------------------------------------------------------ */
1282393Syz155240 /* Function:    iplookup_ioctl                                              */
1292393Syz155240 /* Returns:     int      - 0 = success, else error                          */
1302393Syz155240 /* Parameters:  data(IO) - pointer to ioctl data to be copied to/from user  */
1312393Syz155240 /*                         space.                                           */
1322393Syz155240 /*              cmd(I)   - ioctl command number                             */
1332393Syz155240 /*              mode(I)  - file mode bits used with open                    */
1342393Syz155240 /*                                                                          */
1352393Syz155240 /* Handle ioctl commands sent to the ioctl device.  For the most part, this */
1362393Syz155240 /* involves just calling another function to handle the specifics of each   */
1372393Syz155240 /* command.                                                                 */
1382393Syz155240 /* ------------------------------------------------------------------------ */
ip_lookup_ioctl(data,cmd,mode,uid,ctx,ifs)1393448Sdh155122 int ip_lookup_ioctl(data, cmd, mode, uid, ctx, ifs)
1402393Syz155240 caddr_t data;
1412393Syz155240 ioctlcmd_t cmd;
1423448Sdh155122 int mode, uid;
1433448Sdh155122 void *ctx;
1443448Sdh155122 ipf_stack_t *ifs;
1452393Syz155240 {
1462393Syz155240 	int err;
1472393Syz155240 	SPL_INT(s);
1482393Syz155240 
1492393Syz155240 	mode = mode;	/* LINT */
1502393Syz155240 
1512393Syz155240 	SPL_NET(s);
1522393Syz155240 
1532393Syz155240 	switch (cmd)
1542393Syz155240 	{
1552393Syz155240 	case SIOCLOOKUPADDNODE :
1562393Syz155240 	case SIOCLOOKUPADDNODEW :
1573448Sdh155122 		WRITE_ENTER(&ifs->ifs_ip_poolrw);
1583448Sdh155122 		err = iplookup_addnode(data, ifs);
1593448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1602393Syz155240 		break;
1612393Syz155240 
1622393Syz155240 	case SIOCLOOKUPDELNODE :
1632393Syz155240 	case SIOCLOOKUPDELNODEW :
1643448Sdh155122 		WRITE_ENTER(&ifs->ifs_ip_poolrw);
1653448Sdh155122 		err = iplookup_delnode(data, ifs);
1663448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1672393Syz155240 		break;
1682393Syz155240 
1692393Syz155240 	case SIOCLOOKUPADDTABLE :
1703448Sdh155122 		WRITE_ENTER(&ifs->ifs_ip_poolrw);
1713448Sdh155122 		err = iplookup_addtable(data, ifs);
1723448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1732393Syz155240 		break;
1742393Syz155240 
1752393Syz155240 	case SIOCLOOKUPDELTABLE :
1763448Sdh155122 		WRITE_ENTER(&ifs->ifs_ip_poolrw);
1773448Sdh155122 		err = iplookup_deltable(data, ifs);
1783448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1792393Syz155240 		break;
1802393Syz155240 
1812393Syz155240 	case SIOCLOOKUPSTAT :
1822393Syz155240 	case SIOCLOOKUPSTATW :
1833448Sdh155122 		WRITE_ENTER(&ifs->ifs_ip_poolrw);
1843448Sdh155122 		err = iplookup_stats(data, ifs);
1853448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1862393Syz155240 		break;
1872393Syz155240 
1882393Syz155240 	case SIOCLOOKUPFLUSH :
1893448Sdh155122 		WRITE_ENTER(&ifs->ifs_ip_poolrw);
1903448Sdh155122 		err = iplookup_flush(data, ifs);
1913448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1923448Sdh155122 		break;
1933448Sdh155122 
1943448Sdh155122 	case SIOCLOOKUPITER :
1953448Sdh155122 		err = ip_lookup_iterate(data, uid, ctx, ifs);
1962393Syz155240 		break;
1972393Syz155240 
1982393Syz155240 	default :
1992393Syz155240 		err = EINVAL;
2002393Syz155240 		break;
2012393Syz155240 	}
2022393Syz155240 	SPL_X(s);
2032393Syz155240 	return err;
2042393Syz155240 }
2052393Syz155240 
2062393Syz155240 
2072393Syz155240 /* ------------------------------------------------------------------------ */
2082393Syz155240 /* Function:    iplookup_addnode                                            */
2092393Syz155240 /* Returns:     int     - 0 = success, else error                           */
2102393Syz155240 /* Parameters:  data(I) - pointer to data from ioctl call                   */
2112393Syz155240 /*                                                                          */
2122393Syz155240 /* Add a new data node to a lookup structure.  First, check to see if the   */
2132393Syz155240 /* parent structure refered to by name exists and if it does, then go on to */
2142393Syz155240 /* add a node to it.                                                        */
2152393Syz155240 /* ------------------------------------------------------------------------ */
iplookup_addnode(data,ifs)2163448Sdh155122 static int iplookup_addnode(data, ifs)
2172393Syz155240 caddr_t data;
2183448Sdh155122 ipf_stack_t *ifs;
2192393Syz155240 {
2202393Syz155240 	ip_pool_node_t node, *m;
2212393Syz155240 	iplookupop_t op;
2222393Syz155240 	iphtable_t *iph;
2232393Syz155240 	iphtent_t hte;
2242393Syz155240 	ip_pool_t *p;
2252393Syz155240 	int err;
2262393Syz155240 
227*7433SJohn.Ojemann@Sun.COM 	err = BCOPYIN(data, &op, sizeof(op));
228*7433SJohn.Ojemann@Sun.COM 	if (err != 0)
229*7433SJohn.Ojemann@Sun.COM 		return EFAULT;
230*7433SJohn.Ojemann@Sun.COM 
2312393Syz155240 	op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
2322393Syz155240 
2332393Syz155240 	switch (op.iplo_type)
2342393Syz155240 	{
2352393Syz155240 	case IPLT_POOL :
2362393Syz155240 		if (op.iplo_size != sizeof(node))
2372393Syz155240 			return EINVAL;
2382393Syz155240 
2392393Syz155240 		err = COPYIN(op.iplo_struct, &node, sizeof(node));
2402393Syz155240 		if (err != 0)
2412393Syz155240 			return EFAULT;
2422393Syz155240 
2433448Sdh155122 		p = ip_pool_find(op.iplo_unit, op.iplo_name, ifs);
2442393Syz155240 		if (p == NULL)
2452393Syz155240 			return ESRCH;
2462393Syz155240 
2472393Syz155240 		/*
2482393Syz155240 		 * add an entry to a pool - return an error if it already
2492393Syz155240 		 * exists remove an entry from a pool - if it exists
2502393Syz155240 		 * - in both cases, the pool *must* exist!
2512393Syz155240 		 */
2522393Syz155240 		m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask);
2532393Syz155240 		if (m)
2542393Syz155240 			return EEXIST;
2552393Syz155240 		err = ip_pool_insert(p, &node.ipn_addr,
2563448Sdh155122 				     &node.ipn_mask, node.ipn_info, ifs);
2572393Syz155240 		break;
2582393Syz155240 
2592393Syz155240 	case IPLT_HASH :
2602393Syz155240 		if (op.iplo_size != sizeof(hte))
2612393Syz155240 			return EINVAL;
2622393Syz155240 
2632393Syz155240 		err = COPYIN(op.iplo_struct, &hte, sizeof(hte));
2642393Syz155240 		if (err != 0)
2652393Syz155240 			return EFAULT;
2662393Syz155240 
2673448Sdh155122 		iph = fr_findhtable(op.iplo_unit, op.iplo_name, ifs);
2682393Syz155240 		if (iph == NULL)
2692393Syz155240 			return ESRCH;
2703448Sdh155122 		err = fr_addhtent(iph, &hte, ifs);
2712393Syz155240 		break;
2722393Syz155240 
2732393Syz155240 	default :
2742393Syz155240 		err = EINVAL;
2752393Syz155240 		break;
2762393Syz155240 	}
2772393Syz155240 	return err;
2782393Syz155240 }
2792393Syz155240 
2802393Syz155240 
2812393Syz155240 /* ------------------------------------------------------------------------ */
2822393Syz155240 /* Function:    iplookup_delnode                                            */
2832393Syz155240 /* Returns:     int     - 0 = success, else error                           */
2842393Syz155240 /* Parameters:  data(I) - pointer to data from ioctl call                   */
2852393Syz155240 /*                                                                          */
2862393Syz155240 /* Delete a node from a lookup table by first looking for the table it is   */
2872393Syz155240 /* in and then deleting the entry that gets found.                          */
2882393Syz155240 /* ------------------------------------------------------------------------ */
iplookup_delnode(data,ifs)2893448Sdh155122 static int iplookup_delnode(data, ifs)
2902393Syz155240 caddr_t data;
2913448Sdh155122 ipf_stack_t *ifs;
2922393Syz155240 {
2932393Syz155240 	ip_pool_node_t node, *m;
2942393Syz155240 	iplookupop_t op;
2952393Syz155240 	iphtable_t *iph;
2962393Syz155240 	iphtent_t hte;
2972393Syz155240 	ip_pool_t *p;
2982393Syz155240 	int err;
2992393Syz155240 
300*7433SJohn.Ojemann@Sun.COM 	err = BCOPYIN(data, &op, sizeof(op));
301*7433SJohn.Ojemann@Sun.COM 	if (err != 0)
302*7433SJohn.Ojemann@Sun.COM 		return EFAULT;
3032393Syz155240 
3042393Syz155240 	op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
3052393Syz155240 
3062393Syz155240 	switch (op.iplo_type)
3072393Syz155240 	{
3082393Syz155240 	case IPLT_POOL :
3092393Syz155240 		if (op.iplo_size != sizeof(node))
3102393Syz155240 			return EINVAL;
3112393Syz155240 
3122393Syz155240 		err = COPYIN(op.iplo_struct, &node, sizeof(node));
3132393Syz155240 		if (err != 0)
3142393Syz155240 			return EFAULT;
3152393Syz155240 
3163448Sdh155122 		p = ip_pool_find(op.iplo_unit, op.iplo_name, ifs);
3172393Syz155240 		if (!p)
3182393Syz155240 			return ESRCH;
3192393Syz155240 
3202393Syz155240 		m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask);
3212393Syz155240 		if (m == NULL)
3222393Syz155240 			return ENOENT;
3233448Sdh155122 		err = ip_pool_remove(p, m, ifs);
3242393Syz155240 		break;
3252393Syz155240 
3262393Syz155240 	case IPLT_HASH :
3272393Syz155240 		if (op.iplo_size != sizeof(hte))
3282393Syz155240 			return EINVAL;
3292393Syz155240 
3302393Syz155240 		err = COPYIN(op.iplo_struct, &hte, sizeof(hte));
3312393Syz155240 		if (err != 0)
3322393Syz155240 			return EFAULT;
3332393Syz155240 
3343448Sdh155122 		iph = fr_findhtable(op.iplo_unit, op.iplo_name, ifs);
3352393Syz155240 		if (iph == NULL)
3362393Syz155240 			return ESRCH;
3373448Sdh155122 		err = fr_delhtent(iph, &hte, ifs);
3382393Syz155240 		break;
3392393Syz155240 
3402393Syz155240 	default :
3412393Syz155240 		err = EINVAL;
3422393Syz155240 		break;
3432393Syz155240 	}
3442393Syz155240 	return err;
3452393Syz155240 }
3462393Syz155240 
3472393Syz155240 
3482393Syz155240 /* ------------------------------------------------------------------------ */
3492393Syz155240 /* Function:    iplookup_addtable                                           */
3502393Syz155240 /* Returns:     int     - 0 = success, else error                           */
3512393Syz155240 /* Parameters:  data(I) - pointer to data from ioctl call                   */
3522393Syz155240 /*                                                                          */
3532393Syz155240 /* Create a new lookup table, if one doesn't already exist using the name   */
3542393Syz155240 /* for this one.                                                            */
3552393Syz155240 /* ------------------------------------------------------------------------ */
iplookup_addtable(data,ifs)3563448Sdh155122 static int iplookup_addtable(data, ifs)
3572393Syz155240 caddr_t data;
3583448Sdh155122 ipf_stack_t *ifs;
3592393Syz155240 {
3602393Syz155240 	iplookupop_t op;
3612393Syz155240 	int err;
3622393Syz155240 
363*7433SJohn.Ojemann@Sun.COM 	err = BCOPYIN(data, &op, sizeof(op));
364*7433SJohn.Ojemann@Sun.COM 	if (err != 0)
365*7433SJohn.Ojemann@Sun.COM 		return EFAULT;
3662393Syz155240 
3672393Syz155240 	op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
3682393Syz155240 
3692393Syz155240 	switch (op.iplo_type)
3702393Syz155240 	{
3712393Syz155240 	case IPLT_POOL :
3723448Sdh155122 		if (ip_pool_find(op.iplo_unit, op.iplo_name, ifs) != NULL)
3732393Syz155240 			err = EEXIST;
3742393Syz155240 		else
3753448Sdh155122 			err = ip_pool_create(&op, ifs);
3762393Syz155240 		break;
3772393Syz155240 
3782393Syz155240 	case IPLT_HASH :
3793448Sdh155122 		if (fr_findhtable(op.iplo_unit, op.iplo_name, ifs) != NULL)
3802393Syz155240 			err = EEXIST;
3812393Syz155240 		else
3823448Sdh155122 			err = fr_newhtable(&op, ifs);
3832393Syz155240 		break;
3842393Syz155240 
3852393Syz155240 	default :
3862393Syz155240 		err = EINVAL;
3872393Syz155240 		break;
3882393Syz155240 	}
3892393Syz155240 	return err;
3902393Syz155240 }
3912393Syz155240 
3922393Syz155240 
3932393Syz155240 /* ------------------------------------------------------------------------ */
3942393Syz155240 /* Function:    iplookup_deltable                                           */
3952393Syz155240 /* Returns:     int     - 0 = success, else error                           */
3962393Syz155240 /* Parameters:  data(I) - pointer to data from ioctl call                   */
3972393Syz155240 /*                                                                          */
3982393Syz155240 /* Decodes ioctl request to remove a particular hash table or pool and      */
3992393Syz155240 /* calls the relevant function to do the cleanup.                           */
4002393Syz155240 /* ------------------------------------------------------------------------ */
iplookup_deltable(data,ifs)4013448Sdh155122 static int iplookup_deltable(data, ifs)
4022393Syz155240 caddr_t data;
4033448Sdh155122 ipf_stack_t *ifs;
4042393Syz155240 {
4052393Syz155240 	iplookupop_t op;
4062393Syz155240 	int err;
4072393Syz155240 
408*7433SJohn.Ojemann@Sun.COM 	err = BCOPYIN(data, &op, sizeof(op));
409*7433SJohn.Ojemann@Sun.COM 	if (err != 0)
410*7433SJohn.Ojemann@Sun.COM 		return EFAULT;
411*7433SJohn.Ojemann@Sun.COM 
4122393Syz155240 	op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
4132393Syz155240 
4142393Syz155240 	if (op.iplo_arg & IPLT_ANON)
4152393Syz155240 		op.iplo_arg &= IPLT_ANON;
4162393Syz155240 
4172393Syz155240 	/*
4182393Syz155240 	 * create a new pool - fail if one already exists with
4192393Syz155240 	 * the same #
4202393Syz155240 	 */
4212393Syz155240 	switch (op.iplo_type)
4222393Syz155240 	{
4232393Syz155240 	case IPLT_POOL :
4243448Sdh155122 		err = ip_pool_destroy(&op, ifs);
4252393Syz155240 		break;
4262393Syz155240 
4272393Syz155240 	case IPLT_HASH :
4283448Sdh155122 		err = fr_removehtable(&op, ifs);
4292393Syz155240 		break;
4302393Syz155240 
4312393Syz155240 	default :
4322393Syz155240 		err = EINVAL;
4332393Syz155240 		break;
4342393Syz155240 	}
4352393Syz155240 	return err;
4362393Syz155240 }
4372393Syz155240 
4382393Syz155240 
4392393Syz155240 /* ------------------------------------------------------------------------ */
4402393Syz155240 /* Function:    iplookup_stats                                              */
4412393Syz155240 /* Returns:     int     - 0 = success, else error                           */
4422393Syz155240 /* Parameters:  data(I) - pointer to data from ioctl call                   */
4432393Syz155240 /*                                                                          */
4442393Syz155240 /* Copy statistical information from inside the kernel back to user space.  */
4452393Syz155240 /* ------------------------------------------------------------------------ */
iplookup_stats(data,ifs)4463448Sdh155122 static int iplookup_stats(data, ifs)
4472393Syz155240 caddr_t data;
4483448Sdh155122 ipf_stack_t *ifs;
4492393Syz155240 {
4502393Syz155240 	iplookupop_t op;
4512393Syz155240 	int err;
4522393Syz155240 
453*7433SJohn.Ojemann@Sun.COM 	err = BCOPYIN(data, &op, sizeof(op));
454*7433SJohn.Ojemann@Sun.COM 	if (err != 0)
455*7433SJohn.Ojemann@Sun.COM 		return EFAULT;
4562393Syz155240 
4572393Syz155240 	switch (op.iplo_type)
4582393Syz155240 	{
4592393Syz155240 	case IPLT_POOL :
4603448Sdh155122 		err = ip_pool_statistics(&op, ifs);
4612393Syz155240 		break;
4622393Syz155240 
4632393Syz155240 	case IPLT_HASH :
4643448Sdh155122 		err = fr_gethtablestat(&op, ifs);
4652393Syz155240 		break;
4662393Syz155240 
4672393Syz155240 	default :
4682393Syz155240 		err = EINVAL;
4692393Syz155240 		break;
4702393Syz155240 	}
4712393Syz155240 	return err;
4722393Syz155240 }
4732393Syz155240 
4742393Syz155240 
4752393Syz155240 /* ------------------------------------------------------------------------ */
4762393Syz155240 /* Function:    iplookup_flush                                              */
4772393Syz155240 /* Returns:     int     - 0 = success, else error                           */
4782393Syz155240 /* Parameters:  data(I) - pointer to data from ioctl call                   */
4792393Syz155240 /*                                                                          */
4802393Syz155240 /* A flush is called when we want to flush all the nodes from a particular  */
4812393Syz155240 /* entry in the hash table/pool or want to remove all groups from those.    */
4822393Syz155240 /* ------------------------------------------------------------------------ */
iplookup_flush(data,ifs)4833448Sdh155122 static int iplookup_flush(data, ifs)
4842393Syz155240 caddr_t data;
4853448Sdh155122 ipf_stack_t *ifs;
4862393Syz155240 {
4872393Syz155240 	int err, unit, num, type;
4882393Syz155240 	iplookupflush_t flush;
4892393Syz155240 
490*7433SJohn.Ojemann@Sun.COM 	err = BCOPYIN(data, &flush, sizeof(flush));
491*7433SJohn.Ojemann@Sun.COM 	if (err != 0)
492*7433SJohn.Ojemann@Sun.COM 		return EFAULT;
4932393Syz155240 
4942393Syz155240 	flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0';
4952393Syz155240 
4962393Syz155240 	unit = flush.iplf_unit;
4972393Syz155240 	if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL))
4982393Syz155240 		return EINVAL;
4992393Syz155240 
5002393Syz155240 	type = flush.iplf_type;
5012393Syz155240 	err = EINVAL;
5022393Syz155240 	num = 0;
5032393Syz155240 
5042393Syz155240 	if (type == IPLT_POOL || type == IPLT_ALL) {
5052393Syz155240 		err = 0;
5063448Sdh155122 		num = ip_pool_flush(&flush, ifs);
5072393Syz155240 	}
5082393Syz155240 
5092393Syz155240 	if (type == IPLT_HASH  || type == IPLT_ALL) {
5102393Syz155240 		err = 0;
5113448Sdh155122 		num += fr_flushhtable(&flush, ifs);
5122393Syz155240 	}
5132393Syz155240 
5142393Syz155240 	if (err == 0) {
5152393Syz155240 		flush.iplf_count = num;
5162393Syz155240 		err = COPYOUT(&flush, data, sizeof(flush));
5172393Syz155240 	}
5182393Syz155240 	return err;
5192393Syz155240 }
5202393Syz155240 
5212393Syz155240 
5223448Sdh155122 
ip_lookup_deref(type,ptr,ifs)5233448Sdh155122 void ip_lookup_deref(type, ptr, ifs)
5242393Syz155240 int type;
5252393Syz155240 void *ptr;
5263448Sdh155122 ipf_stack_t *ifs;
5272393Syz155240 {
5282393Syz155240 	if (ptr == NULL)
5292393Syz155240 		return;
5302393Syz155240 
5313448Sdh155122 	WRITE_ENTER(&ifs->ifs_ip_poolrw);
5322393Syz155240 	switch (type)
5332393Syz155240 	{
5342393Syz155240 	case IPLT_POOL :
5353448Sdh155122 		ip_pool_deref(ptr, ifs);
5362393Syz155240 		break;
5372393Syz155240 
5382393Syz155240 	case IPLT_HASH :
5393448Sdh155122 		fr_derefhtable(ptr, ifs);
5402393Syz155240 		break;
5412393Syz155240 	}
5423448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
5433448Sdh155122 }
5443448Sdh155122 
5453448Sdh155122 
ip_lookup_iterate(data,uid,ctx,ifs)5463448Sdh155122 int ip_lookup_iterate(data, uid, ctx, ifs)
5473448Sdh155122 void *data;
5483448Sdh155122 int uid;
5493448Sdh155122 void *ctx;
5503448Sdh155122 ipf_stack_t *ifs;
5513448Sdh155122 {
5523448Sdh155122 	ipflookupiter_t iter;
5533448Sdh155122 	ipftoken_t *token;
5543448Sdh155122 	int err;
5553448Sdh155122 
5563448Sdh155122 	err = fr_inobj(data, &iter, IPFOBJ_LOOKUPITER);
5573448Sdh155122 	if (err != 0) {
5583448Sdh155122 #ifdef _KERNEL
5593448Sdh155122 		(void) printf("fr_inobj\n");
5603448Sdh155122 #endif
5613448Sdh155122 		return err;
5623448Sdh155122 	}
5633448Sdh155122 
5643448Sdh155122 	if (iter.ili_unit < 0 || iter.ili_unit > IPL_LOGMAX) {
5653448Sdh155122 #ifdef _KERNEL
5663448Sdh155122 		(void) printf("unit=%d\n", iter.ili_unit);
5673448Sdh155122 #endif
5683448Sdh155122 		return EINVAL;
5693448Sdh155122 	}
5703448Sdh155122 
5713448Sdh155122 	if (iter.ili_ival != IPFGENITER_LOOKUP) {
5723448Sdh155122 #ifdef _KERNEL
5733448Sdh155122 		(void) printf("ival=%d\n", iter.ili_ival);
5743448Sdh155122 #endif
5753448Sdh155122 		return EINVAL;
5763448Sdh155122 	}
5773448Sdh155122 
5783448Sdh155122 	token = ipf_findtoken(iter.ili_key, uid, ctx, ifs);
5793448Sdh155122 	if (token == NULL) {
5803448Sdh155122 		RWLOCK_EXIT(&ifs->ifs_ipf_tokens);
5813448Sdh155122 		return ESRCH;
5823448Sdh155122 	}
5833448Sdh155122 
5843448Sdh155122 	switch (iter.ili_type)
5853448Sdh155122 	{
5863448Sdh155122 	case IPLT_POOL :
5873448Sdh155122 		err = ip_pool_getnext(token, &iter, ifs);
5883448Sdh155122 		break;
5893448Sdh155122 	case IPLT_HASH :
5903448Sdh155122 		err = fr_htable_getnext(token, &iter, ifs);
5913448Sdh155122 		break;
5923448Sdh155122 	default :
5933448Sdh155122 #ifdef _KERNEL
5943448Sdh155122 		(void) printf("type=%d\n", iter.ili_type);
5953448Sdh155122 #endif
5963448Sdh155122 		err = EINVAL;
5973448Sdh155122 		break;
5983448Sdh155122 	}
5993448Sdh155122 	RWLOCK_EXIT(&ifs->ifs_ipf_tokens);
6003448Sdh155122 
6013448Sdh155122 	return err;
6023448Sdh155122 }
6033448Sdh155122 
6043448Sdh155122 
ip_lookup_iterderef(type,data,ifs)6053448Sdh155122 void ip_lookup_iterderef(type, data, ifs)
6063448Sdh155122 u_32_t type;
6073448Sdh155122 void *data;
6083448Sdh155122 ipf_stack_t *ifs;
6093448Sdh155122 {
6103448Sdh155122 	iplookupiterkey_t	key;
6113448Sdh155122 
6123448Sdh155122 	key.ilik_key = type;
6133448Sdh155122 
6143448Sdh155122 	if (key.ilik_unstr.ilik_ival != IPFGENITER_LOOKUP)
6153448Sdh155122 		return;
6163448Sdh155122 
6173448Sdh155122 	switch (key.ilik_unstr.ilik_type)
6183448Sdh155122 	{
6193448Sdh155122 	case IPLT_HASH :
6203448Sdh155122 		fr_htable_iterderef((u_int)key.ilik_unstr.ilik_otype,
6213448Sdh155122 				    (int)key.ilik_unstr.ilik_unit, data, ifs);
6223448Sdh155122 		break;
6233448Sdh155122 	case IPLT_POOL :
6243448Sdh155122 		ip_pool_iterderef((u_int)key.ilik_unstr.ilik_otype,
6253448Sdh155122 				  (int)key.ilik_unstr.ilik_unit, data, ifs);
6263448Sdh155122 		break;
6273448Sdh155122 	}
6282393Syz155240 }
6292393Syz155240 
6302393Syz155240 
6312393Syz155240 #else /* IPFILTER_LOOKUP */
6322393Syz155240 
6332393Syz155240 /*ARGSUSED*/
ip_lookup_ioctl(data,cmd,mode,uid,ifs)6343448Sdh155122 int ip_lookup_ioctl(data, cmd, mode, uid, ifs)
6352393Syz155240 caddr_t data;
6362393Syz155240 ioctlcmd_t cmd;
6373448Sdh155122 int mode, uid;
6383448Sdh155122 ipf_stack_t *ifs;
6392393Syz155240 {
6402393Syz155240 	return EIO;
6412393Syz155240 }
6422393Syz155240 #endif /* IPFILTER_LOOKUP */
643