17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright (C) 2002-2003 by Darren Reed.
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate *
6bb1d9de5SJohn Ojemann * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
77c478bd9Sstevel@tonic-gate * Use is subject to license terms.
87c478bd9Sstevel@tonic-gate */
97c478bd9Sstevel@tonic-gate
107c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL)
117c478bd9Sstevel@tonic-gate # undef KERNEL
127c478bd9Sstevel@tonic-gate # undef _KERNEL
137c478bd9Sstevel@tonic-gate # define KERNEL 1
147c478bd9Sstevel@tonic-gate # define _KERNEL 1
157c478bd9Sstevel@tonic-gate #endif
16ab25eeb5Syz #if defined(__osf__)
17ab25eeb5Syz # define _PROTO_NET_H_
18ab25eeb5Syz #endif
197c478bd9Sstevel@tonic-gate #include <sys/param.h>
207c478bd9Sstevel@tonic-gate #include <sys/errno.h>
217c478bd9Sstevel@tonic-gate #include <sys/types.h>
227c478bd9Sstevel@tonic-gate #include <sys/time.h>
237c478bd9Sstevel@tonic-gate #include <sys/file.h>
247c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 220000 && defined(_KERNEL)
257c478bd9Sstevel@tonic-gate # include <sys/fcntl.h>
267c478bd9Sstevel@tonic-gate # include <sys/filio.h>
277c478bd9Sstevel@tonic-gate #else
287c478bd9Sstevel@tonic-gate # include <sys/ioctl.h>
297c478bd9Sstevel@tonic-gate #endif
307c478bd9Sstevel@tonic-gate #if !defined(_KERNEL)
317c478bd9Sstevel@tonic-gate # include <string.h>
327c478bd9Sstevel@tonic-gate # define _KERNEL
337c478bd9Sstevel@tonic-gate # ifdef __OpenBSD__
347c478bd9Sstevel@tonic-gate struct file;
357c478bd9Sstevel@tonic-gate # endif
367c478bd9Sstevel@tonic-gate # include <sys/uio.h>
377c478bd9Sstevel@tonic-gate # undef _KERNEL
387c478bd9Sstevel@tonic-gate #endif
397c478bd9Sstevel@tonic-gate #include <sys/socket.h>
40ab25eeb5Syz #if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL)
41ab25eeb5Syz # ifdef __osf__
42ab25eeb5Syz # include <net/radix.h>
43ab25eeb5Syz # endif
44ab25eeb5Syz # include "radix_ipf_local.h"
45ab25eeb5Syz # define _RADIX_H_
46ab25eeb5Syz #endif
477c478bd9Sstevel@tonic-gate #include <net/if.h>
487c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__)
497c478bd9Sstevel@tonic-gate # include <sys/cdefs.h>
507c478bd9Sstevel@tonic-gate # include <sys/proc.h>
517c478bd9Sstevel@tonic-gate #endif
527c478bd9Sstevel@tonic-gate #if defined(_KERNEL)
537c478bd9Sstevel@tonic-gate # include <sys/systm.h>
547c478bd9Sstevel@tonic-gate # if !defined(__SVR4) && !defined(__svr4__)
557c478bd9Sstevel@tonic-gate # include <sys/mbuf.h>
567c478bd9Sstevel@tonic-gate # endif
577c478bd9Sstevel@tonic-gate #endif
587c478bd9Sstevel@tonic-gate #include <netinet/in.h>
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h"
617c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h"
627c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h"
637c478bd9Sstevel@tonic-gate #include "netinet/ip_htable.h"
647c478bd9Sstevel@tonic-gate #include "netinet/ip_lookup.h"
65f4b3ec61Sdh #include "netinet/ipf_stack.h"
66ab25eeb5Syz /* END OF INCLUDES */
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate #if !defined(lint)
69ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.7 2005/06/12 07:18:20 darrenr Exp $";
707c478bd9Sstevel@tonic-gate #endif
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOOKUP
73f4b3ec61Sdh static int iplookup_addnode __P((caddr_t, ipf_stack_t *));
74f4b3ec61Sdh static int iplookup_delnode __P((caddr_t data, ipf_stack_t *));
75f4b3ec61Sdh static int iplookup_addtable __P((caddr_t, ipf_stack_t *));
76f4b3ec61Sdh static int iplookup_deltable __P((caddr_t, ipf_stack_t *));
77f4b3ec61Sdh static int iplookup_stats __P((caddr_t, ipf_stack_t *));
78f4b3ec61Sdh static int iplookup_flush __P((caddr_t, ipf_stack_t *));
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate
82ab25eeb5Syz /* ------------------------------------------------------------------------ */
83ab25eeb5Syz /* Function: iplookup_init */
84ab25eeb5Syz /* Returns: int - 0 = success, else error */
85ab25eeb5Syz /* Parameters: Nil */
86ab25eeb5Syz /* */
87ab25eeb5Syz /* Initialise all of the subcomponents of the lookup infrstructure. */
88ab25eeb5Syz /* ------------------------------------------------------------------------ */
ip_lookup_init(ifs)89f4b3ec61Sdh int ip_lookup_init(ifs)
90f4b3ec61Sdh ipf_stack_t *ifs;
917c478bd9Sstevel@tonic-gate {
92ab25eeb5Syz
93f4b3ec61Sdh if (ip_pool_init(ifs) == -1)
947c478bd9Sstevel@tonic-gate return -1;
957c478bd9Sstevel@tonic-gate
96f4b3ec61Sdh RWLOCK_INIT(&ifs->ifs_ip_poolrw, "ip pool rwlock");
977c478bd9Sstevel@tonic-gate
98f4b3ec61Sdh ifs->ifs_ip_lookup_inited = 1;
99f4b3ec61Sdh ifs->ifs_ipftokenhead = NULL;
100f4b3ec61Sdh ifs->ifs_ipftokentail = &ifs->ifs_ipftokenhead;
1017c478bd9Sstevel@tonic-gate return 0;
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate
105ab25eeb5Syz /* ------------------------------------------------------------------------ */
106ab25eeb5Syz /* Function: iplookup_unload */
107ab25eeb5Syz /* Returns: int - 0 = success, else error */
108ab25eeb5Syz /* Parameters: Nil */
109ab25eeb5Syz /* */
110ab25eeb5Syz /* Free up all pool related memory that has been allocated whilst IPFilter */
111ab25eeb5Syz /* has been running. Also, do any other deinitialisation required such */
112ab25eeb5Syz /* ip_lookup_init() can be called again, safely. */
113ab25eeb5Syz /* ------------------------------------------------------------------------ */
ip_lookup_unload(ifs)114f4b3ec61Sdh void ip_lookup_unload(ifs)
115f4b3ec61Sdh ipf_stack_t *ifs;
1167c478bd9Sstevel@tonic-gate {
117f4b3ec61Sdh ip_pool_fini(ifs);
118f4b3ec61Sdh fr_htable_unload(ifs);
1197c478bd9Sstevel@tonic-gate
120f4b3ec61Sdh if (ifs->ifs_ip_lookup_inited == 1) {
121f4b3ec61Sdh RW_DESTROY(&ifs->ifs_ip_poolrw);
122f4b3ec61Sdh ifs->ifs_ip_lookup_inited = 0;
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate
127ab25eeb5Syz /* ------------------------------------------------------------------------ */
128ab25eeb5Syz /* Function: iplookup_ioctl */
129ab25eeb5Syz /* Returns: int - 0 = success, else error */
130ab25eeb5Syz /* Parameters: data(IO) - pointer to ioctl data to be copied to/from user */
131ab25eeb5Syz /* space. */
132ab25eeb5Syz /* cmd(I) - ioctl command number */
133ab25eeb5Syz /* mode(I) - file mode bits used with open */
134ab25eeb5Syz /* */
135ab25eeb5Syz /* Handle ioctl commands sent to the ioctl device. For the most part, this */
136ab25eeb5Syz /* involves just calling another function to handle the specifics of each */
137ab25eeb5Syz /* command. */
138ab25eeb5Syz /* ------------------------------------------------------------------------ */
ip_lookup_ioctl(data,cmd,mode,uid,ctx,ifs)139f4b3ec61Sdh int ip_lookup_ioctl(data, cmd, mode, uid, ctx, ifs)
1407c478bd9Sstevel@tonic-gate caddr_t data;
141ab25eeb5Syz ioctlcmd_t cmd;
142f4b3ec61Sdh int mode, uid;
143f4b3ec61Sdh void *ctx;
144f4b3ec61Sdh ipf_stack_t *ifs;
1457c478bd9Sstevel@tonic-gate {
1467c478bd9Sstevel@tonic-gate int err;
147ab25eeb5Syz SPL_INT(s);
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate mode = mode; /* LINT */
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate SPL_NET(s);
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate switch (cmd)
1547c478bd9Sstevel@tonic-gate {
1557c478bd9Sstevel@tonic-gate case SIOCLOOKUPADDNODE :
156ab25eeb5Syz case SIOCLOOKUPADDNODEW :
157f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
158f4b3ec61Sdh err = iplookup_addnode(data, ifs);
159f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1607c478bd9Sstevel@tonic-gate break;
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate case SIOCLOOKUPDELNODE :
163ab25eeb5Syz case SIOCLOOKUPDELNODEW :
164f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
165f4b3ec61Sdh err = iplookup_delnode(data, ifs);
166f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1677c478bd9Sstevel@tonic-gate break;
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate case SIOCLOOKUPADDTABLE :
170f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
171f4b3ec61Sdh err = iplookup_addtable(data, ifs);
172f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1737c478bd9Sstevel@tonic-gate break;
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate case SIOCLOOKUPDELTABLE :
176f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
177f4b3ec61Sdh err = iplookup_deltable(data, ifs);
178f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1797c478bd9Sstevel@tonic-gate break;
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate case SIOCLOOKUPSTAT :
182ab25eeb5Syz case SIOCLOOKUPSTATW :
183f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
184f4b3ec61Sdh err = iplookup_stats(data, ifs);
185f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
1867c478bd9Sstevel@tonic-gate break;
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate case SIOCLOOKUPFLUSH :
189f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
190f4b3ec61Sdh err = iplookup_flush(data, ifs);
191f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
192f4b3ec61Sdh break;
193f4b3ec61Sdh
194f4b3ec61Sdh case SIOCLOOKUPITER :
195f4b3ec61Sdh err = ip_lookup_iterate(data, uid, ctx, ifs);
1967c478bd9Sstevel@tonic-gate break;
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate default :
1997c478bd9Sstevel@tonic-gate err = EINVAL;
2007c478bd9Sstevel@tonic-gate break;
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate SPL_X(s);
2037c478bd9Sstevel@tonic-gate return err;
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate
207ab25eeb5Syz /* ------------------------------------------------------------------------ */
208ab25eeb5Syz /* Function: iplookup_addnode */
209ab25eeb5Syz /* Returns: int - 0 = success, else error */
210ab25eeb5Syz /* Parameters: data(I) - pointer to data from ioctl call */
211ab25eeb5Syz /* */
212ab25eeb5Syz /* Add a new data node to a lookup structure. First, check to see if the */
213ab25eeb5Syz /* parent structure refered to by name exists and if it does, then go on to */
214ab25eeb5Syz /* add a node to it. */
215ab25eeb5Syz /* ------------------------------------------------------------------------ */
iplookup_addnode(data,ifs)216f4b3ec61Sdh static int iplookup_addnode(data, ifs)
2177c478bd9Sstevel@tonic-gate caddr_t data;
218f4b3ec61Sdh ipf_stack_t *ifs;
2197c478bd9Sstevel@tonic-gate {
2207c478bd9Sstevel@tonic-gate ip_pool_node_t node, *m;
2217c478bd9Sstevel@tonic-gate iplookupop_t op;
2227c478bd9Sstevel@tonic-gate iphtable_t *iph;
2237c478bd9Sstevel@tonic-gate iphtent_t hte;
2247c478bd9Sstevel@tonic-gate ip_pool_t *p;
2257c478bd9Sstevel@tonic-gate int err;
2267c478bd9Sstevel@tonic-gate
227bb1d9de5SJohn Ojemann err = BCOPYIN(data, &op, sizeof(op));
228bb1d9de5SJohn Ojemann if (err != 0)
229bb1d9de5SJohn Ojemann return EFAULT;
230bb1d9de5SJohn Ojemann
2317c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate switch (op.iplo_type)
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate case IPLT_POOL :
2367c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(node))
2377c478bd9Sstevel@tonic-gate return EINVAL;
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &node, sizeof(node));
2407c478bd9Sstevel@tonic-gate if (err != 0)
2417c478bd9Sstevel@tonic-gate return EFAULT;
2427c478bd9Sstevel@tonic-gate
243f4b3ec61Sdh p = ip_pool_find(op.iplo_unit, op.iplo_name, ifs);
2447c478bd9Sstevel@tonic-gate if (p == NULL)
2457c478bd9Sstevel@tonic-gate return ESRCH;
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate /*
2487c478bd9Sstevel@tonic-gate * add an entry to a pool - return an error if it already
2497c478bd9Sstevel@tonic-gate * exists remove an entry from a pool - if it exists
2507c478bd9Sstevel@tonic-gate * - in both cases, the pool *must* exist!
2517c478bd9Sstevel@tonic-gate */
2527663b816Sml m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask);
2537c478bd9Sstevel@tonic-gate if (m)
2547c478bd9Sstevel@tonic-gate return EEXIST;
2557663b816Sml err = ip_pool_insert(p, &node.ipn_addr,
256f4b3ec61Sdh &node.ipn_mask, node.ipn_info, ifs);
2577c478bd9Sstevel@tonic-gate break;
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate case IPLT_HASH :
2607c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(hte))
2617c478bd9Sstevel@tonic-gate return EINVAL;
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &hte, sizeof(hte));
2647c478bd9Sstevel@tonic-gate if (err != 0)
2657c478bd9Sstevel@tonic-gate return EFAULT;
2667c478bd9Sstevel@tonic-gate
267f4b3ec61Sdh iph = fr_findhtable(op.iplo_unit, op.iplo_name, ifs);
2687c478bd9Sstevel@tonic-gate if (iph == NULL)
2697c478bd9Sstevel@tonic-gate return ESRCH;
270f4b3ec61Sdh err = fr_addhtent(iph, &hte, ifs);
2717c478bd9Sstevel@tonic-gate break;
2727c478bd9Sstevel@tonic-gate
2737c478bd9Sstevel@tonic-gate default :
2747c478bd9Sstevel@tonic-gate err = EINVAL;
2757c478bd9Sstevel@tonic-gate break;
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate return err;
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate
2807c478bd9Sstevel@tonic-gate
281ab25eeb5Syz /* ------------------------------------------------------------------------ */
282ab25eeb5Syz /* Function: iplookup_delnode */
283ab25eeb5Syz /* Returns: int - 0 = success, else error */
284ab25eeb5Syz /* Parameters: data(I) - pointer to data from ioctl call */
285ab25eeb5Syz /* */
286ab25eeb5Syz /* Delete a node from a lookup table by first looking for the table it is */
287ab25eeb5Syz /* in and then deleting the entry that gets found. */
288ab25eeb5Syz /* ------------------------------------------------------------------------ */
iplookup_delnode(data,ifs)289f4b3ec61Sdh static int iplookup_delnode(data, ifs)
2907c478bd9Sstevel@tonic-gate caddr_t data;
291f4b3ec61Sdh ipf_stack_t *ifs;
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate ip_pool_node_t node, *m;
2947c478bd9Sstevel@tonic-gate iplookupop_t op;
2957c478bd9Sstevel@tonic-gate iphtable_t *iph;
2967c478bd9Sstevel@tonic-gate iphtent_t hte;
2977c478bd9Sstevel@tonic-gate ip_pool_t *p;
2987c478bd9Sstevel@tonic-gate int err;
2997c478bd9Sstevel@tonic-gate
300bb1d9de5SJohn Ojemann err = BCOPYIN(data, &op, sizeof(op));
301bb1d9de5SJohn Ojemann if (err != 0)
302bb1d9de5SJohn Ojemann return EFAULT;
303ab25eeb5Syz
3047c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate switch (op.iplo_type)
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate case IPLT_POOL :
3097c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(node))
3107c478bd9Sstevel@tonic-gate return EINVAL;
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &node, sizeof(node));
3137c478bd9Sstevel@tonic-gate if (err != 0)
3147c478bd9Sstevel@tonic-gate return EFAULT;
3157c478bd9Sstevel@tonic-gate
316f4b3ec61Sdh p = ip_pool_find(op.iplo_unit, op.iplo_name, ifs);
3177c478bd9Sstevel@tonic-gate if (!p)
3187c478bd9Sstevel@tonic-gate return ESRCH;
3197c478bd9Sstevel@tonic-gate
3207663b816Sml m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask);
3217c478bd9Sstevel@tonic-gate if (m == NULL)
3227c478bd9Sstevel@tonic-gate return ENOENT;
323f4b3ec61Sdh err = ip_pool_remove(p, m, ifs);
3247c478bd9Sstevel@tonic-gate break;
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate case IPLT_HASH :
3277c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(hte))
3287c478bd9Sstevel@tonic-gate return EINVAL;
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &hte, sizeof(hte));
3317c478bd9Sstevel@tonic-gate if (err != 0)
3327c478bd9Sstevel@tonic-gate return EFAULT;
3337c478bd9Sstevel@tonic-gate
334f4b3ec61Sdh iph = fr_findhtable(op.iplo_unit, op.iplo_name, ifs);
3357c478bd9Sstevel@tonic-gate if (iph == NULL)
3367c478bd9Sstevel@tonic-gate return ESRCH;
337f4b3ec61Sdh err = fr_delhtent(iph, &hte, ifs);
3387c478bd9Sstevel@tonic-gate break;
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate default :
3417c478bd9Sstevel@tonic-gate err = EINVAL;
3427c478bd9Sstevel@tonic-gate break;
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate return err;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate
348ab25eeb5Syz /* ------------------------------------------------------------------------ */
349ab25eeb5Syz /* Function: iplookup_addtable */
350ab25eeb5Syz /* Returns: int - 0 = success, else error */
351ab25eeb5Syz /* Parameters: data(I) - pointer to data from ioctl call */
352ab25eeb5Syz /* */
353ab25eeb5Syz /* Create a new lookup table, if one doesn't already exist using the name */
354ab25eeb5Syz /* for this one. */
355ab25eeb5Syz /* ------------------------------------------------------------------------ */
iplookup_addtable(data,ifs)356f4b3ec61Sdh static int iplookup_addtable(data, ifs)
3577c478bd9Sstevel@tonic-gate caddr_t data;
358f4b3ec61Sdh ipf_stack_t *ifs;
3597c478bd9Sstevel@tonic-gate {
3607c478bd9Sstevel@tonic-gate iplookupop_t op;
3617c478bd9Sstevel@tonic-gate int err;
3627c478bd9Sstevel@tonic-gate
363bb1d9de5SJohn Ojemann err = BCOPYIN(data, &op, sizeof(op));
364bb1d9de5SJohn Ojemann if (err != 0)
365bb1d9de5SJohn Ojemann return EFAULT;
366ab25eeb5Syz
3677c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate switch (op.iplo_type)
3707c478bd9Sstevel@tonic-gate {
3717c478bd9Sstevel@tonic-gate case IPLT_POOL :
372f4b3ec61Sdh if (ip_pool_find(op.iplo_unit, op.iplo_name, ifs) != NULL)
3737c478bd9Sstevel@tonic-gate err = EEXIST;
3747c478bd9Sstevel@tonic-gate else
375f4b3ec61Sdh err = ip_pool_create(&op, ifs);
3767c478bd9Sstevel@tonic-gate break;
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate case IPLT_HASH :
379f4b3ec61Sdh if (fr_findhtable(op.iplo_unit, op.iplo_name, ifs) != NULL)
3807c478bd9Sstevel@tonic-gate err = EEXIST;
3817c478bd9Sstevel@tonic-gate else
382f4b3ec61Sdh err = fr_newhtable(&op, ifs);
3837c478bd9Sstevel@tonic-gate break;
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate default :
3867c478bd9Sstevel@tonic-gate err = EINVAL;
3877c478bd9Sstevel@tonic-gate break;
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate return err;
3907c478bd9Sstevel@tonic-gate }
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
3947c478bd9Sstevel@tonic-gate /* Function: iplookup_deltable */
3957c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */
3967c478bd9Sstevel@tonic-gate /* Parameters: data(I) - pointer to data from ioctl call */
3977c478bd9Sstevel@tonic-gate /* */
3987c478bd9Sstevel@tonic-gate /* Decodes ioctl request to remove a particular hash table or pool and */
3997c478bd9Sstevel@tonic-gate /* calls the relevant function to do the cleanup. */
4007c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
iplookup_deltable(data,ifs)401f4b3ec61Sdh static int iplookup_deltable(data, ifs)
4027c478bd9Sstevel@tonic-gate caddr_t data;
403f4b3ec61Sdh ipf_stack_t *ifs;
4047c478bd9Sstevel@tonic-gate {
4057c478bd9Sstevel@tonic-gate iplookupop_t op;
4067c478bd9Sstevel@tonic-gate int err;
4077c478bd9Sstevel@tonic-gate
408bb1d9de5SJohn Ojemann err = BCOPYIN(data, &op, sizeof(op));
409bb1d9de5SJohn Ojemann if (err != 0)
410bb1d9de5SJohn Ojemann return EFAULT;
411bb1d9de5SJohn Ojemann
4127c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate if (op.iplo_arg & IPLT_ANON)
4157c478bd9Sstevel@tonic-gate op.iplo_arg &= IPLT_ANON;
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate /*
4187c478bd9Sstevel@tonic-gate * create a new pool - fail if one already exists with
4197c478bd9Sstevel@tonic-gate * the same #
4207c478bd9Sstevel@tonic-gate */
4217c478bd9Sstevel@tonic-gate switch (op.iplo_type)
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate case IPLT_POOL :
424f4b3ec61Sdh err = ip_pool_destroy(&op, ifs);
4257c478bd9Sstevel@tonic-gate break;
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate case IPLT_HASH :
428f4b3ec61Sdh err = fr_removehtable(&op, ifs);
4297c478bd9Sstevel@tonic-gate break;
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate default :
4327c478bd9Sstevel@tonic-gate err = EINVAL;
4337c478bd9Sstevel@tonic-gate break;
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate return err;
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
4407c478bd9Sstevel@tonic-gate /* Function: iplookup_stats */
4417c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */
4427c478bd9Sstevel@tonic-gate /* Parameters: data(I) - pointer to data from ioctl call */
4437c478bd9Sstevel@tonic-gate /* */
4447c478bd9Sstevel@tonic-gate /* Copy statistical information from inside the kernel back to user space. */
4457c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
iplookup_stats(data,ifs)446f4b3ec61Sdh static int iplookup_stats(data, ifs)
4477c478bd9Sstevel@tonic-gate caddr_t data;
448f4b3ec61Sdh ipf_stack_t *ifs;
4497c478bd9Sstevel@tonic-gate {
4507c478bd9Sstevel@tonic-gate iplookupop_t op;
4517663b816Sml int err;
4527c478bd9Sstevel@tonic-gate
453bb1d9de5SJohn Ojemann err = BCOPYIN(data, &op, sizeof(op));
454bb1d9de5SJohn Ojemann if (err != 0)
455bb1d9de5SJohn Ojemann return EFAULT;
4567c478bd9Sstevel@tonic-gate
4577663b816Sml switch (op.iplo_type)
4587663b816Sml {
4597663b816Sml case IPLT_POOL :
460f4b3ec61Sdh err = ip_pool_statistics(&op, ifs);
4617663b816Sml break;
4627663b816Sml
4637663b816Sml case IPLT_HASH :
464f4b3ec61Sdh err = fr_gethtablestat(&op, ifs);
4657663b816Sml break;
4667c478bd9Sstevel@tonic-gate
4677663b816Sml default :
4687663b816Sml err = EINVAL;
4697663b816Sml break;
4707663b816Sml }
4717c478bd9Sstevel@tonic-gate return err;
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
4767c478bd9Sstevel@tonic-gate /* Function: iplookup_flush */
4777c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */
4787c478bd9Sstevel@tonic-gate /* Parameters: data(I) - pointer to data from ioctl call */
4797c478bd9Sstevel@tonic-gate /* */
4807c478bd9Sstevel@tonic-gate /* A flush is called when we want to flush all the nodes from a particular */
4817c478bd9Sstevel@tonic-gate /* entry in the hash table/pool or want to remove all groups from those. */
4827c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */
iplookup_flush(data,ifs)483f4b3ec61Sdh static int iplookup_flush(data, ifs)
4847c478bd9Sstevel@tonic-gate caddr_t data;
485f4b3ec61Sdh ipf_stack_t *ifs;
4867c478bd9Sstevel@tonic-gate {
487ab25eeb5Syz int err, unit, num, type;
488ab25eeb5Syz iplookupflush_t flush;
4897c478bd9Sstevel@tonic-gate
490bb1d9de5SJohn Ojemann err = BCOPYIN(data, &flush, sizeof(flush));
491bb1d9de5SJohn Ojemann if (err != 0)
492bb1d9de5SJohn Ojemann return EFAULT;
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0';
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate unit = flush.iplf_unit;
4977c478bd9Sstevel@tonic-gate if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL))
4987c478bd9Sstevel@tonic-gate return EINVAL;
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate type = flush.iplf_type;
5017c478bd9Sstevel@tonic-gate err = EINVAL;
5027c478bd9Sstevel@tonic-gate num = 0;
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate if (type == IPLT_POOL || type == IPLT_ALL) {
5057c478bd9Sstevel@tonic-gate err = 0;
506f4b3ec61Sdh num = ip_pool_flush(&flush, ifs);
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate if (type == IPLT_HASH || type == IPLT_ALL) {
5107c478bd9Sstevel@tonic-gate err = 0;
511f4b3ec61Sdh num += fr_flushhtable(&flush, ifs);
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate
5147c478bd9Sstevel@tonic-gate if (err == 0) {
5157c478bd9Sstevel@tonic-gate flush.iplf_count = num;
5167c478bd9Sstevel@tonic-gate err = COPYOUT(&flush, data, sizeof(flush));
5177c478bd9Sstevel@tonic-gate }
5187c478bd9Sstevel@tonic-gate return err;
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate
522f4b3ec61Sdh
ip_lookup_deref(type,ptr,ifs)523f4b3ec61Sdh void ip_lookup_deref(type, ptr, ifs)
5247c478bd9Sstevel@tonic-gate int type;
5257c478bd9Sstevel@tonic-gate void *ptr;
526f4b3ec61Sdh ipf_stack_t *ifs;
5277c478bd9Sstevel@tonic-gate {
5287c478bd9Sstevel@tonic-gate if (ptr == NULL)
5297c478bd9Sstevel@tonic-gate return;
5307c478bd9Sstevel@tonic-gate
531f4b3ec61Sdh WRITE_ENTER(&ifs->ifs_ip_poolrw);
5327c478bd9Sstevel@tonic-gate switch (type)
5337c478bd9Sstevel@tonic-gate {
5347c478bd9Sstevel@tonic-gate case IPLT_POOL :
535f4b3ec61Sdh ip_pool_deref(ptr, ifs);
536f4b3ec61Sdh break;
537f4b3ec61Sdh
538f4b3ec61Sdh case IPLT_HASH :
539f4b3ec61Sdh fr_derefhtable(ptr, ifs);
540f4b3ec61Sdh break;
541f4b3ec61Sdh }
542f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
543f4b3ec61Sdh }
544f4b3ec61Sdh
545*55fea89dSDan Cross
ip_lookup_iterate(data,uid,ctx,ifs)546f4b3ec61Sdh int ip_lookup_iterate(data, uid, ctx, ifs)
547f4b3ec61Sdh void *data;
548f4b3ec61Sdh int uid;
549f4b3ec61Sdh void *ctx;
550f4b3ec61Sdh ipf_stack_t *ifs;
551f4b3ec61Sdh {
552f4b3ec61Sdh ipflookupiter_t iter;
553f4b3ec61Sdh ipftoken_t *token;
554f4b3ec61Sdh int err;
555f4b3ec61Sdh
556f4b3ec61Sdh err = fr_inobj(data, &iter, IPFOBJ_LOOKUPITER);
557f4b3ec61Sdh if (err != 0) {
558f4b3ec61Sdh #ifdef _KERNEL
559f4b3ec61Sdh (void) printf("fr_inobj\n");
560f4b3ec61Sdh #endif
561f4b3ec61Sdh return err;
562f4b3ec61Sdh }
563f4b3ec61Sdh
564f4b3ec61Sdh if (iter.ili_unit < 0 || iter.ili_unit > IPL_LOGMAX) {
565f4b3ec61Sdh #ifdef _KERNEL
566f4b3ec61Sdh (void) printf("unit=%d\n", iter.ili_unit);
567f4b3ec61Sdh #endif
568f4b3ec61Sdh return EINVAL;
569f4b3ec61Sdh }
570f4b3ec61Sdh
571f4b3ec61Sdh if (iter.ili_ival != IPFGENITER_LOOKUP) {
572f4b3ec61Sdh #ifdef _KERNEL
573f4b3ec61Sdh (void) printf("ival=%d\n", iter.ili_ival);
574f4b3ec61Sdh #endif
575f4b3ec61Sdh return EINVAL;
576f4b3ec61Sdh }
577f4b3ec61Sdh
578f4b3ec61Sdh token = ipf_findtoken(iter.ili_key, uid, ctx, ifs);
579f4b3ec61Sdh if (token == NULL) {
580f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ipf_tokens);
581f4b3ec61Sdh return ESRCH;
582f4b3ec61Sdh }
583f4b3ec61Sdh
584f4b3ec61Sdh switch (iter.ili_type)
585f4b3ec61Sdh {
586f4b3ec61Sdh case IPLT_POOL :
587f4b3ec61Sdh err = ip_pool_getnext(token, &iter, ifs);
588f4b3ec61Sdh break;
589f4b3ec61Sdh case IPLT_HASH :
590f4b3ec61Sdh err = fr_htable_getnext(token, &iter, ifs);
591f4b3ec61Sdh break;
592f4b3ec61Sdh default :
593f4b3ec61Sdh #ifdef _KERNEL
594f4b3ec61Sdh (void) printf("type=%d\n", iter.ili_type);
595f4b3ec61Sdh #endif
596f4b3ec61Sdh err = EINVAL;
5977c478bd9Sstevel@tonic-gate break;
598f4b3ec61Sdh }
599f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ipf_tokens);
600ab25eeb5Syz
601f4b3ec61Sdh return err;
602f4b3ec61Sdh }
603f4b3ec61Sdh
604f4b3ec61Sdh
ip_lookup_iterderef(type,data,ifs)605f4b3ec61Sdh void ip_lookup_iterderef(type, data, ifs)
606f4b3ec61Sdh u_32_t type;
607f4b3ec61Sdh void *data;
608f4b3ec61Sdh ipf_stack_t *ifs;
609f4b3ec61Sdh {
610f4b3ec61Sdh iplookupiterkey_t key;
611f4b3ec61Sdh
612f4b3ec61Sdh key.ilik_key = type;
613f4b3ec61Sdh
614f4b3ec61Sdh if (key.ilik_unstr.ilik_ival != IPFGENITER_LOOKUP)
615f4b3ec61Sdh return;
616f4b3ec61Sdh
617f4b3ec61Sdh switch (key.ilik_unstr.ilik_type)
618f4b3ec61Sdh {
6197c478bd9Sstevel@tonic-gate case IPLT_HASH :
620f4b3ec61Sdh fr_htable_iterderef((u_int)key.ilik_unstr.ilik_otype,
621f4b3ec61Sdh (int)key.ilik_unstr.ilik_unit, data, ifs);
622f4b3ec61Sdh break;
623f4b3ec61Sdh case IPLT_POOL :
624f4b3ec61Sdh ip_pool_iterderef((u_int)key.ilik_unstr.ilik_otype,
625f4b3ec61Sdh (int)key.ilik_unstr.ilik_unit, data, ifs);
6267c478bd9Sstevel@tonic-gate break;
6277c478bd9Sstevel@tonic-gate }
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate #else /* IPFILTER_LOOKUP */
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate /*ARGSUSED*/
ip_lookup_ioctl(data,cmd,mode,uid,ifs)634f4b3ec61Sdh int ip_lookup_ioctl(data, cmd, mode, uid, ifs)
6357c478bd9Sstevel@tonic-gate caddr_t data;
636ab25eeb5Syz ioctlcmd_t cmd;
637f4b3ec61Sdh int mode, uid;
638f4b3ec61Sdh ipf_stack_t *ifs;
6397c478bd9Sstevel@tonic-gate {
6407c478bd9Sstevel@tonic-gate return EIO;
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOOKUP */
643