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