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 * 6*ab25eeb5Syz * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 77c478bd9Sstevel@tonic-gate * Use is subject to license terms. 87c478bd9Sstevel@tonic-gate */ 97c478bd9Sstevel@tonic-gate 107c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL) 137c478bd9Sstevel@tonic-gate # undef KERNEL 147c478bd9Sstevel@tonic-gate # undef _KERNEL 157c478bd9Sstevel@tonic-gate # define KERNEL 1 167c478bd9Sstevel@tonic-gate # define _KERNEL 1 177c478bd9Sstevel@tonic-gate #endif 18*ab25eeb5Syz #if defined(__osf__) 19*ab25eeb5Syz # define _PROTO_NET_H_ 20*ab25eeb5Syz #endif 217c478bd9Sstevel@tonic-gate #include <sys/param.h> 227c478bd9Sstevel@tonic-gate #include <sys/errno.h> 237c478bd9Sstevel@tonic-gate #include <sys/types.h> 247c478bd9Sstevel@tonic-gate #include <sys/time.h> 257c478bd9Sstevel@tonic-gate #include <sys/file.h> 267c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 220000 && defined(_KERNEL) 277c478bd9Sstevel@tonic-gate # include <sys/fcntl.h> 287c478bd9Sstevel@tonic-gate # include <sys/filio.h> 297c478bd9Sstevel@tonic-gate #else 307c478bd9Sstevel@tonic-gate # include <sys/ioctl.h> 317c478bd9Sstevel@tonic-gate #endif 327c478bd9Sstevel@tonic-gate #if !defined(_KERNEL) 337c478bd9Sstevel@tonic-gate # include <string.h> 347c478bd9Sstevel@tonic-gate # define _KERNEL 357c478bd9Sstevel@tonic-gate # ifdef __OpenBSD__ 367c478bd9Sstevel@tonic-gate struct file; 377c478bd9Sstevel@tonic-gate # endif 387c478bd9Sstevel@tonic-gate # include <sys/uio.h> 397c478bd9Sstevel@tonic-gate # undef _KERNEL 407c478bd9Sstevel@tonic-gate #endif 417c478bd9Sstevel@tonic-gate #include <sys/socket.h> 42*ab25eeb5Syz #if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) 43*ab25eeb5Syz # ifdef __osf__ 44*ab25eeb5Syz # include <net/radix.h> 45*ab25eeb5Syz # endif 46*ab25eeb5Syz # include "radix_ipf_local.h" 47*ab25eeb5Syz # define _RADIX_H_ 48*ab25eeb5Syz #endif 497c478bd9Sstevel@tonic-gate #include <net/if.h> 507c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__) 517c478bd9Sstevel@tonic-gate # include <sys/cdefs.h> 527c478bd9Sstevel@tonic-gate # include <sys/proc.h> 537c478bd9Sstevel@tonic-gate #endif 547c478bd9Sstevel@tonic-gate #if defined(_KERNEL) 557c478bd9Sstevel@tonic-gate # include <sys/systm.h> 567c478bd9Sstevel@tonic-gate # if !defined(__SVR4) && !defined(__svr4__) 577c478bd9Sstevel@tonic-gate # include <sys/mbuf.h> 587c478bd9Sstevel@tonic-gate # endif 597c478bd9Sstevel@tonic-gate #endif 607c478bd9Sstevel@tonic-gate #include <netinet/in.h> 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h" 637c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h" 647c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h" 657c478bd9Sstevel@tonic-gate #include "netinet/ip_htable.h" 667c478bd9Sstevel@tonic-gate #include "netinet/ip_lookup.h" 67*ab25eeb5Syz /* END OF INCLUDES */ 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #if !defined(lint) 70*ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.7 2005/06/12 07:18:20 darrenr Exp $"; 717c478bd9Sstevel@tonic-gate #endif 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOOKUP 747c478bd9Sstevel@tonic-gate int ip_lookup_inited = 0; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate static int iplookup_addnode __P((caddr_t)); 777c478bd9Sstevel@tonic-gate static int iplookup_delnode __P((caddr_t data)); 787c478bd9Sstevel@tonic-gate static int iplookup_addtable __P((caddr_t)); 797c478bd9Sstevel@tonic-gate static int iplookup_deltable __P((caddr_t)); 807c478bd9Sstevel@tonic-gate static int iplookup_stats __P((caddr_t)); 817c478bd9Sstevel@tonic-gate static int iplookup_flush __P((caddr_t)); 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate 84*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 85*ab25eeb5Syz /* Function: iplookup_init */ 86*ab25eeb5Syz /* Returns: int - 0 = success, else error */ 87*ab25eeb5Syz /* Parameters: Nil */ 88*ab25eeb5Syz /* */ 89*ab25eeb5Syz /* Initialise all of the subcomponents of the lookup infrstructure. */ 90*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 917c478bd9Sstevel@tonic-gate int ip_lookup_init() 927c478bd9Sstevel@tonic-gate { 93*ab25eeb5Syz 947c478bd9Sstevel@tonic-gate if (ip_pool_init() == -1) 957c478bd9Sstevel@tonic-gate return -1; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate RWLOCK_INIT(&ip_poolrw, "ip pool rwlock"); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate ip_lookup_inited = 1; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate return 0; 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate 105*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 106*ab25eeb5Syz /* Function: iplookup_unload */ 107*ab25eeb5Syz /* Returns: int - 0 = success, else error */ 108*ab25eeb5Syz /* Parameters: Nil */ 109*ab25eeb5Syz /* */ 110*ab25eeb5Syz /* Free up all pool related memory that has been allocated whilst IPFilter */ 111*ab25eeb5Syz /* has been running. Also, do any other deinitialisation required such */ 112*ab25eeb5Syz /* ip_lookup_init() can be called again, safely. */ 113*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 1147c478bd9Sstevel@tonic-gate void ip_lookup_unload() 1157c478bd9Sstevel@tonic-gate { 1167c478bd9Sstevel@tonic-gate ip_pool_fini(); 1177c478bd9Sstevel@tonic-gate fr_htable_unload(); 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate if (ip_lookup_inited == 1) { 1207c478bd9Sstevel@tonic-gate RW_DESTROY(&ip_poolrw); 1217c478bd9Sstevel@tonic-gate ip_lookup_inited = 0; 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate 126*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 127*ab25eeb5Syz /* Function: iplookup_ioctl */ 128*ab25eeb5Syz /* Returns: int - 0 = success, else error */ 129*ab25eeb5Syz /* Parameters: data(IO) - pointer to ioctl data to be copied to/from user */ 130*ab25eeb5Syz /* space. */ 131*ab25eeb5Syz /* cmd(I) - ioctl command number */ 132*ab25eeb5Syz /* mode(I) - file mode bits used with open */ 133*ab25eeb5Syz /* */ 134*ab25eeb5Syz /* Handle ioctl commands sent to the ioctl device. For the most part, this */ 135*ab25eeb5Syz /* involves just calling another function to handle the specifics of each */ 136*ab25eeb5Syz /* command. */ 137*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 1387c478bd9Sstevel@tonic-gate int ip_lookup_ioctl(data, cmd, mode) 1397c478bd9Sstevel@tonic-gate caddr_t data; 140*ab25eeb5Syz ioctlcmd_t cmd; 1417c478bd9Sstevel@tonic-gate int mode; 1427c478bd9Sstevel@tonic-gate { 1437c478bd9Sstevel@tonic-gate int err; 144*ab25eeb5Syz SPL_INT(s); 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate mode = mode; /* LINT */ 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate SPL_NET(s); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate switch (cmd) 1517c478bd9Sstevel@tonic-gate { 1527c478bd9Sstevel@tonic-gate case SIOCLOOKUPADDNODE : 153*ab25eeb5Syz case SIOCLOOKUPADDNODEW : 1547c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 1557c478bd9Sstevel@tonic-gate err = iplookup_addnode(data); 1567c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 1577c478bd9Sstevel@tonic-gate break; 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate case SIOCLOOKUPDELNODE : 160*ab25eeb5Syz case SIOCLOOKUPDELNODEW : 1617c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 1627c478bd9Sstevel@tonic-gate err = iplookup_delnode(data); 1637c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 1647c478bd9Sstevel@tonic-gate break; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate case SIOCLOOKUPADDTABLE : 1677c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 1687c478bd9Sstevel@tonic-gate err = iplookup_addtable(data); 1697c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 1707c478bd9Sstevel@tonic-gate break; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate case SIOCLOOKUPDELTABLE : 1737c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 1747c478bd9Sstevel@tonic-gate err = iplookup_deltable(data); 1757c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 1767c478bd9Sstevel@tonic-gate break; 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate case SIOCLOOKUPSTAT : 179*ab25eeb5Syz case SIOCLOOKUPSTATW : 1807c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 1817c478bd9Sstevel@tonic-gate err = iplookup_stats(data); 1827c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 1837c478bd9Sstevel@tonic-gate break; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate case SIOCLOOKUPFLUSH : 1867c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 1877c478bd9Sstevel@tonic-gate err = iplookup_flush(data); 1887c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate default : 1927c478bd9Sstevel@tonic-gate err = EINVAL; 1937c478bd9Sstevel@tonic-gate break; 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate SPL_X(s); 1967c478bd9Sstevel@tonic-gate return err; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate 200*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 201*ab25eeb5Syz /* Function: iplookup_addnode */ 202*ab25eeb5Syz /* Returns: int - 0 = success, else error */ 203*ab25eeb5Syz /* Parameters: data(I) - pointer to data from ioctl call */ 204*ab25eeb5Syz /* */ 205*ab25eeb5Syz /* Add a new data node to a lookup structure. First, check to see if the */ 206*ab25eeb5Syz /* parent structure refered to by name exists and if it does, then go on to */ 207*ab25eeb5Syz /* add a node to it. */ 208*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 2097c478bd9Sstevel@tonic-gate static int iplookup_addnode(data) 2107c478bd9Sstevel@tonic-gate caddr_t data; 2117c478bd9Sstevel@tonic-gate { 2127c478bd9Sstevel@tonic-gate ip_pool_node_t node, *m; 2137c478bd9Sstevel@tonic-gate iplookupop_t op; 2147c478bd9Sstevel@tonic-gate iphtable_t *iph; 2157c478bd9Sstevel@tonic-gate iphtent_t hte; 2167c478bd9Sstevel@tonic-gate ip_pool_t *p; 2177c478bd9Sstevel@tonic-gate int err; 2187c478bd9Sstevel@tonic-gate 219*ab25eeb5Syz err = 0; 220*ab25eeb5Syz BCOPYIN(data, &op, sizeof(op)); 2217c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate switch (op.iplo_type) 2247c478bd9Sstevel@tonic-gate { 2257c478bd9Sstevel@tonic-gate case IPLT_POOL : 2267c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(node)) 2277c478bd9Sstevel@tonic-gate return EINVAL; 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &node, sizeof(node)); 2307c478bd9Sstevel@tonic-gate if (err != 0) 2317c478bd9Sstevel@tonic-gate return EFAULT; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate p = ip_pool_find(op.iplo_unit, op.iplo_name); 2347c478bd9Sstevel@tonic-gate if (p == NULL) 2357c478bd9Sstevel@tonic-gate return ESRCH; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* 2387c478bd9Sstevel@tonic-gate * add an entry to a pool - return an error if it already 2397c478bd9Sstevel@tonic-gate * exists remove an entry from a pool - if it exists 2407c478bd9Sstevel@tonic-gate * - in both cases, the pool *must* exist! 2417c478bd9Sstevel@tonic-gate */ 2427663b816Sml m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); 2437c478bd9Sstevel@tonic-gate if (m) 2447c478bd9Sstevel@tonic-gate return EEXIST; 2457663b816Sml err = ip_pool_insert(p, &node.ipn_addr, 2467663b816Sml &node.ipn_mask, node.ipn_info); 2477c478bd9Sstevel@tonic-gate break; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate case IPLT_HASH : 2507c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(hte)) 2517c478bd9Sstevel@tonic-gate return EINVAL; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); 2547c478bd9Sstevel@tonic-gate if (err != 0) 2557c478bd9Sstevel@tonic-gate return EFAULT; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate iph = fr_findhtable(op.iplo_unit, op.iplo_name); 2587c478bd9Sstevel@tonic-gate if (iph == NULL) 2597c478bd9Sstevel@tonic-gate return ESRCH; 2607c478bd9Sstevel@tonic-gate err = fr_addhtent(iph, &hte); 2617c478bd9Sstevel@tonic-gate break; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate default : 2647c478bd9Sstevel@tonic-gate err = EINVAL; 2657c478bd9Sstevel@tonic-gate break; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate return err; 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate 271*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 272*ab25eeb5Syz /* Function: iplookup_delnode */ 273*ab25eeb5Syz /* Returns: int - 0 = success, else error */ 274*ab25eeb5Syz /* Parameters: data(I) - pointer to data from ioctl call */ 275*ab25eeb5Syz /* */ 276*ab25eeb5Syz /* Delete a node from a lookup table by first looking for the table it is */ 277*ab25eeb5Syz /* in and then deleting the entry that gets found. */ 278*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 2797c478bd9Sstevel@tonic-gate static int iplookup_delnode(data) 2807c478bd9Sstevel@tonic-gate caddr_t data; 2817c478bd9Sstevel@tonic-gate { 2827c478bd9Sstevel@tonic-gate ip_pool_node_t node, *m; 2837c478bd9Sstevel@tonic-gate iplookupop_t op; 2847c478bd9Sstevel@tonic-gate iphtable_t *iph; 2857c478bd9Sstevel@tonic-gate iphtent_t hte; 2867c478bd9Sstevel@tonic-gate ip_pool_t *p; 2877c478bd9Sstevel@tonic-gate int err; 2887c478bd9Sstevel@tonic-gate 289*ab25eeb5Syz err = 0; 290*ab25eeb5Syz BCOPYIN(data, &op, sizeof(op)); 291*ab25eeb5Syz 2927c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate switch (op.iplo_type) 2957c478bd9Sstevel@tonic-gate { 2967c478bd9Sstevel@tonic-gate case IPLT_POOL : 2977c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(node)) 2987c478bd9Sstevel@tonic-gate return EINVAL; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &node, sizeof(node)); 3017c478bd9Sstevel@tonic-gate if (err != 0) 3027c478bd9Sstevel@tonic-gate return EFAULT; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate p = ip_pool_find(op.iplo_unit, op.iplo_name); 3057c478bd9Sstevel@tonic-gate if (!p) 3067c478bd9Sstevel@tonic-gate return ESRCH; 3077c478bd9Sstevel@tonic-gate 3087663b816Sml m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); 3097c478bd9Sstevel@tonic-gate if (m == NULL) 3107c478bd9Sstevel@tonic-gate return ENOENT; 3117c478bd9Sstevel@tonic-gate err = ip_pool_remove(p, m); 3127c478bd9Sstevel@tonic-gate break; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate case IPLT_HASH : 3157c478bd9Sstevel@tonic-gate if (op.iplo_size != sizeof(hte)) 3167c478bd9Sstevel@tonic-gate return EINVAL; 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); 3197c478bd9Sstevel@tonic-gate if (err != 0) 3207c478bd9Sstevel@tonic-gate return EFAULT; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate iph = fr_findhtable(op.iplo_unit, op.iplo_name); 3237c478bd9Sstevel@tonic-gate if (iph == NULL) 3247c478bd9Sstevel@tonic-gate return ESRCH; 3257c478bd9Sstevel@tonic-gate err = fr_delhtent(iph, &hte); 3267c478bd9Sstevel@tonic-gate break; 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate default : 3297c478bd9Sstevel@tonic-gate err = EINVAL; 3307c478bd9Sstevel@tonic-gate break; 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate return err; 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate 336*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 337*ab25eeb5Syz /* Function: iplookup_addtable */ 338*ab25eeb5Syz /* Returns: int - 0 = success, else error */ 339*ab25eeb5Syz /* Parameters: data(I) - pointer to data from ioctl call */ 340*ab25eeb5Syz /* */ 341*ab25eeb5Syz /* Create a new lookup table, if one doesn't already exist using the name */ 342*ab25eeb5Syz /* for this one. */ 343*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 3447c478bd9Sstevel@tonic-gate static int iplookup_addtable(data) 3457c478bd9Sstevel@tonic-gate caddr_t data; 3467c478bd9Sstevel@tonic-gate { 3477c478bd9Sstevel@tonic-gate iplookupop_t op; 3487c478bd9Sstevel@tonic-gate int err; 3497c478bd9Sstevel@tonic-gate 350*ab25eeb5Syz err = 0; 351*ab25eeb5Syz BCOPYIN(data, &op, sizeof(op)); 352*ab25eeb5Syz 3537c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate switch (op.iplo_type) 3567c478bd9Sstevel@tonic-gate { 3577c478bd9Sstevel@tonic-gate case IPLT_POOL : 3587c478bd9Sstevel@tonic-gate if (ip_pool_find(op.iplo_unit, op.iplo_name) != NULL) 3597c478bd9Sstevel@tonic-gate err = EEXIST; 3607c478bd9Sstevel@tonic-gate else 3617c478bd9Sstevel@tonic-gate err = ip_pool_create(&op); 3627c478bd9Sstevel@tonic-gate break; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate case IPLT_HASH : 3657c478bd9Sstevel@tonic-gate if (fr_findhtable(op.iplo_unit, op.iplo_name) != NULL) 3667c478bd9Sstevel@tonic-gate err = EEXIST; 3677c478bd9Sstevel@tonic-gate else 3687c478bd9Sstevel@tonic-gate err = fr_newhtable(&op); 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate default : 3727c478bd9Sstevel@tonic-gate err = EINVAL; 3737c478bd9Sstevel@tonic-gate break; 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate return err; 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3807c478bd9Sstevel@tonic-gate /* Function: iplookup_deltable */ 3817c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 3827c478bd9Sstevel@tonic-gate /* Parameters: data(I) - pointer to data from ioctl call */ 3837c478bd9Sstevel@tonic-gate /* */ 3847c478bd9Sstevel@tonic-gate /* Decodes ioctl request to remove a particular hash table or pool and */ 3857c478bd9Sstevel@tonic-gate /* calls the relevant function to do the cleanup. */ 3867c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3877c478bd9Sstevel@tonic-gate static int iplookup_deltable(data) 3887c478bd9Sstevel@tonic-gate caddr_t data; 3897c478bd9Sstevel@tonic-gate { 3907c478bd9Sstevel@tonic-gate iplookupop_t op; 3917c478bd9Sstevel@tonic-gate int err; 3927c478bd9Sstevel@tonic-gate 393*ab25eeb5Syz BCOPYIN(data, &op, sizeof(op)); 3947c478bd9Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate if (op.iplo_arg & IPLT_ANON) 3977c478bd9Sstevel@tonic-gate op.iplo_arg &= IPLT_ANON; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate /* 4007c478bd9Sstevel@tonic-gate * create a new pool - fail if one already exists with 4017c478bd9Sstevel@tonic-gate * the same # 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate switch (op.iplo_type) 4047c478bd9Sstevel@tonic-gate { 4057c478bd9Sstevel@tonic-gate case IPLT_POOL : 4067c478bd9Sstevel@tonic-gate err = ip_pool_destroy(&op); 4077c478bd9Sstevel@tonic-gate break; 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate case IPLT_HASH : 4107c478bd9Sstevel@tonic-gate err = fr_removehtable(&op); 4117c478bd9Sstevel@tonic-gate break; 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate default : 4147c478bd9Sstevel@tonic-gate err = EINVAL; 4157c478bd9Sstevel@tonic-gate break; 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate return err; 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4227c478bd9Sstevel@tonic-gate /* Function: iplookup_stats */ 4237c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 4247c478bd9Sstevel@tonic-gate /* Parameters: data(I) - pointer to data from ioctl call */ 4257c478bd9Sstevel@tonic-gate /* */ 4267c478bd9Sstevel@tonic-gate /* Copy statistical information from inside the kernel back to user space. */ 4277c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4287c478bd9Sstevel@tonic-gate static int iplookup_stats(data) 4297c478bd9Sstevel@tonic-gate caddr_t data; 4307c478bd9Sstevel@tonic-gate { 4317c478bd9Sstevel@tonic-gate iplookupop_t op; 4327663b816Sml int err; 4337c478bd9Sstevel@tonic-gate 4347663b816Sml err = 0; 435*ab25eeb5Syz BCOPYIN(data, &op, sizeof(op)); 4367c478bd9Sstevel@tonic-gate 4377663b816Sml switch (op.iplo_type) 4387663b816Sml { 4397663b816Sml case IPLT_POOL : 4407663b816Sml err = ip_pool_statistics(&op); 4417663b816Sml break; 4427663b816Sml 4437663b816Sml case IPLT_HASH : 4447663b816Sml err = fr_gethtablestat(&op); 4457663b816Sml break; 4467c478bd9Sstevel@tonic-gate 4477663b816Sml default : 4487663b816Sml err = EINVAL; 4497663b816Sml break; 4507663b816Sml } 4517c478bd9Sstevel@tonic-gate return err; 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4567c478bd9Sstevel@tonic-gate /* Function: iplookup_flush */ 4577c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 4587c478bd9Sstevel@tonic-gate /* Parameters: data(I) - pointer to data from ioctl call */ 4597c478bd9Sstevel@tonic-gate /* */ 4607c478bd9Sstevel@tonic-gate /* A flush is called when we want to flush all the nodes from a particular */ 4617c478bd9Sstevel@tonic-gate /* entry in the hash table/pool or want to remove all groups from those. */ 4627c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4637c478bd9Sstevel@tonic-gate static int iplookup_flush(data) 4647c478bd9Sstevel@tonic-gate caddr_t data; 4657c478bd9Sstevel@tonic-gate { 466*ab25eeb5Syz int err, unit, num, type; 467*ab25eeb5Syz iplookupflush_t flush; 4687c478bd9Sstevel@tonic-gate 469*ab25eeb5Syz err = 0; 470*ab25eeb5Syz BCOPYIN(data, &flush, sizeof(flush)); 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate unit = flush.iplf_unit; 4757c478bd9Sstevel@tonic-gate if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) 4767c478bd9Sstevel@tonic-gate return EINVAL; 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate type = flush.iplf_type; 4797c478bd9Sstevel@tonic-gate err = EINVAL; 4807c478bd9Sstevel@tonic-gate num = 0; 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate if (type == IPLT_POOL || type == IPLT_ALL) { 4837c478bd9Sstevel@tonic-gate err = 0; 484*ab25eeb5Syz num = ip_pool_flush(&flush); 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate if (type == IPLT_HASH || type == IPLT_ALL) { 4887c478bd9Sstevel@tonic-gate err = 0; 489*ab25eeb5Syz num += fr_flushhtable(&flush); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate if (err == 0) { 4937c478bd9Sstevel@tonic-gate flush.iplf_count = num; 4947c478bd9Sstevel@tonic-gate err = COPYOUT(&flush, data, sizeof(flush)); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate return err; 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate void ip_lookup_deref(type, ptr) 5017c478bd9Sstevel@tonic-gate int type; 5027c478bd9Sstevel@tonic-gate void *ptr; 5037c478bd9Sstevel@tonic-gate { 5047c478bd9Sstevel@tonic-gate if (ptr == NULL) 5057c478bd9Sstevel@tonic-gate return; 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate WRITE_ENTER(&ip_poolrw); 5087c478bd9Sstevel@tonic-gate switch (type) 5097c478bd9Sstevel@tonic-gate { 5107c478bd9Sstevel@tonic-gate case IPLT_POOL : 5117c478bd9Sstevel@tonic-gate ip_pool_deref(ptr); 5127c478bd9Sstevel@tonic-gate break; 513*ab25eeb5Syz 5147c478bd9Sstevel@tonic-gate case IPLT_HASH : 5157c478bd9Sstevel@tonic-gate fr_derefhtable(ptr); 5167c478bd9Sstevel@tonic-gate break; 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate #else /* IPFILTER_LOOKUP */ 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5257c478bd9Sstevel@tonic-gate int ip_lookup_ioctl(data, cmd, mode) 5267c478bd9Sstevel@tonic-gate caddr_t data; 527*ab25eeb5Syz ioctlcmd_t cmd; 5287c478bd9Sstevel@tonic-gate int mode; 5297c478bd9Sstevel@tonic-gate { 5307c478bd9Sstevel@tonic-gate return EIO; 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOOKUP */ 533