17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright (C) 1993-2001, 2003 by Darren Reed.
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate *
6*de22af4eSJohn Ojemann * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
77c478bd9Sstevel@tonic-gate */
87c478bd9Sstevel@tonic-gate
97c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL)
107c478bd9Sstevel@tonic-gate # undef KERNEL
117c478bd9Sstevel@tonic-gate # undef _KERNEL
127c478bd9Sstevel@tonic-gate # define KERNEL 1
137c478bd9Sstevel@tonic-gate # define _KERNEL 1
147c478bd9Sstevel@tonic-gate #endif
157c478bd9Sstevel@tonic-gate #include <sys/param.h>
167c478bd9Sstevel@tonic-gate #include <sys/types.h>
177c478bd9Sstevel@tonic-gate #include <sys/errno.h>
187c478bd9Sstevel@tonic-gate #include <sys/time.h>
197c478bd9Sstevel@tonic-gate #include <sys/file.h>
207c478bd9Sstevel@tonic-gate #if !defined(_KERNEL)
217c478bd9Sstevel@tonic-gate # include <stdlib.h>
227c478bd9Sstevel@tonic-gate # include <string.h>
237c478bd9Sstevel@tonic-gate # define _KERNEL
247c478bd9Sstevel@tonic-gate # ifdef __OpenBSD__
257c478bd9Sstevel@tonic-gate struct file;
267c478bd9Sstevel@tonic-gate # endif
277c478bd9Sstevel@tonic-gate # include <sys/uio.h>
287c478bd9Sstevel@tonic-gate # undef _KERNEL
297c478bd9Sstevel@tonic-gate #endif
307c478bd9Sstevel@tonic-gate #include <sys/socket.h>
317c478bd9Sstevel@tonic-gate #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
327c478bd9Sstevel@tonic-gate # include <sys/malloc.h>
337c478bd9Sstevel@tonic-gate #endif
347c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__)
357c478bd9Sstevel@tonic-gate # include <sys/cdefs.h>
367c478bd9Sstevel@tonic-gate # include <sys/proc.h>
377c478bd9Sstevel@tonic-gate #endif
38ab25eeb5Syz #if !defined(__svr4__) && !defined(__SVR4) && !defined(__hpux) && \
39ab25eeb5Syz !defined(linux)
407c478bd9Sstevel@tonic-gate # include <sys/mbuf.h>
417c478bd9Sstevel@tonic-gate #endif
427c478bd9Sstevel@tonic-gate #if defined(_KERNEL)
437c478bd9Sstevel@tonic-gate # include <sys/systm.h>
447c478bd9Sstevel@tonic-gate #else
457c478bd9Sstevel@tonic-gate # include <stdio.h>
467c478bd9Sstevel@tonic-gate #endif
477c478bd9Sstevel@tonic-gate #include <netinet/in.h>
487c478bd9Sstevel@tonic-gate #include <net/if.h>
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h"
517c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h"
527c478bd9Sstevel@tonic-gate #include "netinet/ip_lookup.h"
537c478bd9Sstevel@tonic-gate #include "netinet/ip_htable.h"
54f4b3ec61Sdh #include "netinet/ipf_stack.h"
55ab25eeb5Syz /* END OF INCLUDES */
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate #if !defined(lint)
58ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.3 2005/05/14 05:11:38 darrenr Exp $";
597c478bd9Sstevel@tonic-gate #endif
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOOKUP
627c478bd9Sstevel@tonic-gate static iphtent_t *fr_iphmfind __P((iphtable_t *, struct in_addr *));
637663b816Sml #ifdef USE_INET6
647663b816Sml static iphtent_t *fr_iphmfind6 __P((iphtable_t *, struct in6_addr *));
657663b816Sml static uint32_t sum4(uint32_t *);
667663b816Sml static void left_shift_ipv6 __P((char *));
677663b816Sml #endif
687c478bd9Sstevel@tonic-gate
fr_htable_unload(ifs)69f4b3ec61Sdh void fr_htable_unload(ifs)
70f4b3ec61Sdh ipf_stack_t *ifs;
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate iplookupflush_t fop;
73ab25eeb5Syz
74ab25eeb5Syz fop.iplf_unit = IPL_LOGALL;
75f4b3ec61Sdh (void)fr_flushhtable(&fop, ifs);
767c478bd9Sstevel@tonic-gate }
777c478bd9Sstevel@tonic-gate
78ab25eeb5Syz
fr_gethtablestat(op,ifs)79f4b3ec61Sdh int fr_gethtablestat(op, ifs)
807663b816Sml iplookupop_t *op;
81f4b3ec61Sdh ipf_stack_t *ifs;
827663b816Sml {
837663b816Sml iphtstat_t stats;
847663b816Sml
857663b816Sml if (op->iplo_size != sizeof(stats))
867663b816Sml return EINVAL;
877663b816Sml
88f4b3ec61Sdh stats.iphs_tables = ifs->ifs_ipf_htables[op->iplo_unit];
89f4b3ec61Sdh stats.iphs_numtables = ifs->ifs_ipf_nhtables[op->iplo_unit];
90f4b3ec61Sdh stats.iphs_numnodes = ifs->ifs_ipf_nhtnodes[op->iplo_unit];
91f4b3ec61Sdh stats.iphs_nomem = ifs->ifs_ipht_nomem[op->iplo_unit];
927663b816Sml
937663b816Sml return COPYOUT(&stats, op->iplo_struct, sizeof(stats));
947663b816Sml
957663b816Sml }
967663b816Sml
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate /*
997c478bd9Sstevel@tonic-gate * Create a new hash table using the template passed.
1007c478bd9Sstevel@tonic-gate */
fr_newhtable(op,ifs)101f4b3ec61Sdh int fr_newhtable(op, ifs)
1027c478bd9Sstevel@tonic-gate iplookupop_t *op;
103f4b3ec61Sdh ipf_stack_t *ifs;
1047c478bd9Sstevel@tonic-gate {
1057c478bd9Sstevel@tonic-gate iphtable_t *iph, *oiph;
1067c478bd9Sstevel@tonic-gate char name[FR_GROUPLEN];
1077c478bd9Sstevel@tonic-gate int err, i, unit;
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate KMALLOC(iph, iphtable_t *);
110ab25eeb5Syz if (iph == NULL) {
111f4b3ec61Sdh ifs->ifs_ipht_nomem[op->iplo_unit]++;
112ab25eeb5Syz return ENOMEM;
113ab25eeb5Syz }
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
1167c478bd9Sstevel@tonic-gate if (err != 0) {
1177c478bd9Sstevel@tonic-gate KFREE(iph);
1187c478bd9Sstevel@tonic-gate return EFAULT;
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate unit = op->iplo_unit;
1227c478bd9Sstevel@tonic-gate if (iph->iph_unit != unit) {
1237c478bd9Sstevel@tonic-gate KFREE(iph);
1247c478bd9Sstevel@tonic-gate return EINVAL;
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate if ((op->iplo_arg & IPHASH_ANON) == 0) {
128f4b3ec61Sdh if (fr_findhtable(op->iplo_unit, op->iplo_name, ifs) != NULL) {
1297c478bd9Sstevel@tonic-gate KFREE(iph);
1307c478bd9Sstevel@tonic-gate return EEXIST;
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate } else {
1337c478bd9Sstevel@tonic-gate i = IPHASH_ANON;
1347c478bd9Sstevel@tonic-gate do {
1357c478bd9Sstevel@tonic-gate i++;
136ab25eeb5Syz #if defined(SNPRINTF) && defined(_KERNEL)
137ab25eeb5Syz (void)SNPRINTF(name, sizeof(name), "%u", i);
138ab25eeb5Syz #else
1397c478bd9Sstevel@tonic-gate (void)sprintf(name, "%u", i);
140ab25eeb5Syz #endif
141f4b3ec61Sdh for (oiph = ifs->ifs_ipf_htables[unit]; oiph != NULL;
1427c478bd9Sstevel@tonic-gate oiph = oiph->iph_next)
1437c478bd9Sstevel@tonic-gate if (strncmp(oiph->iph_name, name,
1447c478bd9Sstevel@tonic-gate sizeof(oiph->iph_name)) == 0)
1457c478bd9Sstevel@tonic-gate break;
1467c478bd9Sstevel@tonic-gate } while (oiph != NULL);
1477c478bd9Sstevel@tonic-gate (void)strncpy(iph->iph_name, name, sizeof(iph->iph_name));
1487c478bd9Sstevel@tonic-gate err = COPYOUT(iph, op->iplo_struct, sizeof(*iph));
1497c478bd9Sstevel@tonic-gate if (err != 0) {
1507c478bd9Sstevel@tonic-gate KFREE(iph);
1517c478bd9Sstevel@tonic-gate return EFAULT;
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate iph->iph_type |= IPHASH_ANON;
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate KMALLOCS(iph->iph_table, iphtent_t **,
1577c478bd9Sstevel@tonic-gate iph->iph_size * sizeof(*iph->iph_table));
1587c478bd9Sstevel@tonic-gate if (iph->iph_table == NULL) {
1597c478bd9Sstevel@tonic-gate KFREE(iph);
160f4b3ec61Sdh ifs->ifs_ipht_nomem[unit]++;
1617c478bd9Sstevel@tonic-gate return ENOMEM;
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
1657663b816Sml iph->iph_masks[0] = 0;
1667663b816Sml iph->iph_masks[1] = 0;
1677663b816Sml iph->iph_masks[2] = 0;
1687663b816Sml iph->iph_masks[3] = 0;
169f4b3ec61Sdh iph->iph_list = NULL;
1707c478bd9Sstevel@tonic-gate
171f4b3ec61Sdh iph->iph_ref = 1;
172f4b3ec61Sdh iph->iph_next = ifs->ifs_ipf_htables[unit];
173f4b3ec61Sdh iph->iph_pnext = &ifs->ifs_ipf_htables[unit];
174f4b3ec61Sdh if (ifs->ifs_ipf_htables[unit] != NULL)
175f4b3ec61Sdh ifs->ifs_ipf_htables[unit]->iph_pnext = &iph->iph_next;
176f4b3ec61Sdh ifs->ifs_ipf_htables[unit] = iph;
1777663b816Sml
178f4b3ec61Sdh ifs->ifs_ipf_nhtables[unit]++;
1797663b816Sml
1807c478bd9Sstevel@tonic-gate return 0;
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate */
fr_removehtable(op,ifs)186f4b3ec61Sdh int fr_removehtable(op, ifs)
1877c478bd9Sstevel@tonic-gate iplookupop_t *op;
188f4b3ec61Sdh ipf_stack_t *ifs;
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate iphtable_t *iph;
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate
193f4b3ec61Sdh iph = fr_findhtable(op->iplo_unit, op->iplo_name, ifs);
1947c478bd9Sstevel@tonic-gate if (iph == NULL)
1957c478bd9Sstevel@tonic-gate return ESRCH;
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate if (iph->iph_unit != op->iplo_unit) {
1987c478bd9Sstevel@tonic-gate return EINVAL;
1997c478bd9Sstevel@tonic-gate }
200f4b3ec61Sdh
201f4b3ec61Sdh if (iph->iph_ref != 1) {
2027c478bd9Sstevel@tonic-gate return EBUSY;
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate
205f4b3ec61Sdh fr_delhtable(iph, ifs);
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate return 0;
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate
fr_delhtable(iph,ifs)211f4b3ec61Sdh void fr_delhtable(iph, ifs)
2127c478bd9Sstevel@tonic-gate iphtable_t *iph;
213f4b3ec61Sdh ipf_stack_t *ifs;
2147c478bd9Sstevel@tonic-gate {
215ab25eeb5Syz iphtent_t *ipe;
216ab25eeb5Syz int i;
217ab25eeb5Syz
218ab25eeb5Syz for (i = 0; i < iph->iph_size; i++)
219ab25eeb5Syz while ((ipe = iph->iph_table[i]) != NULL)
220f4b3ec61Sdh if (fr_delhtent(iph, ipe, ifs) != 0)
221ab25eeb5Syz return;
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate *iph->iph_pnext = iph->iph_next;
2247c478bd9Sstevel@tonic-gate if (iph->iph_next != NULL)
2257c478bd9Sstevel@tonic-gate iph->iph_next->iph_pnext = iph->iph_pnext;
2267c478bd9Sstevel@tonic-gate
227f4b3ec61Sdh ifs->ifs_ipf_nhtables[iph->iph_unit]--;
228ab25eeb5Syz
229f4b3ec61Sdh if (iph->iph_ref == 1) {
230ab25eeb5Syz KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
231ab25eeb5Syz KFREE(iph);
232ab25eeb5Syz }
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate
fr_derefhtable(iph,ifs)236f4b3ec61Sdh void fr_derefhtable(iph, ifs)
2377c478bd9Sstevel@tonic-gate iphtable_t *iph;
238f4b3ec61Sdh ipf_stack_t *ifs;
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate iph->iph_ref--;
2417c478bd9Sstevel@tonic-gate if (iph->iph_ref == 0)
242f4b3ec61Sdh fr_delhtable(iph, ifs);
243f4b3ec61Sdh }
244f4b3ec61Sdh
245f4b3ec61Sdh
fr_derefhtent(ipe)246f4b3ec61Sdh void fr_derefhtent(ipe)
247f4b3ec61Sdh iphtent_t *ipe;
248f4b3ec61Sdh {
249f4b3ec61Sdh ipe->ipe_ref--;
250f4b3ec61Sdh if (ipe->ipe_ref == 0) {
251f4b3ec61Sdh KFREE(ipe);
252f4b3ec61Sdh }
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate
fr_findhtable(unit,name,ifs)256f4b3ec61Sdh iphtable_t *fr_findhtable(unit, name, ifs)
2577c478bd9Sstevel@tonic-gate int unit;
2587c478bd9Sstevel@tonic-gate char *name;
259f4b3ec61Sdh ipf_stack_t *ifs;
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate iphtable_t *iph;
2627c478bd9Sstevel@tonic-gate
263f4b3ec61Sdh for (iph = ifs->ifs_ipf_htables[unit]; iph != NULL; iph = iph->iph_next)
2647c478bd9Sstevel@tonic-gate if (strncmp(iph->iph_name, name, sizeof(iph->iph_name)) == 0)
2657c478bd9Sstevel@tonic-gate break;
2667c478bd9Sstevel@tonic-gate return iph;
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate
fr_flushhtable(op,ifs)270f4b3ec61Sdh size_t fr_flushhtable(op, ifs)
2717c478bd9Sstevel@tonic-gate iplookupflush_t *op;
272f4b3ec61Sdh ipf_stack_t *ifs;
2737c478bd9Sstevel@tonic-gate {
2747c478bd9Sstevel@tonic-gate iphtable_t *iph;
275ab25eeb5Syz size_t freed;
276ab25eeb5Syz int i;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate freed = 0;
2797c478bd9Sstevel@tonic-gate
280ab25eeb5Syz for (i = 0; i <= IPL_LOGMAX; i++) {
281ab25eeb5Syz if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) {
282f4b3ec61Sdh while ((iph = ifs->ifs_ipf_htables[i]) != NULL) {
283f4b3ec61Sdh fr_delhtable(iph, ifs);
284ab25eeb5Syz freed++;
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate }
287ab25eeb5Syz }
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate return freed;
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate /*
2947c478bd9Sstevel@tonic-gate * Add an entry to a hash table.
2957c478bd9Sstevel@tonic-gate */
fr_addhtent(iph,ipeo,ifs)296f4b3ec61Sdh int fr_addhtent(iph, ipeo, ifs)
2977c478bd9Sstevel@tonic-gate iphtable_t *iph;
2987c478bd9Sstevel@tonic-gate iphtent_t *ipeo;
299f4b3ec61Sdh ipf_stack_t *ifs;
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate iphtent_t *ipe;
3027c478bd9Sstevel@tonic-gate u_int hv;
3037c478bd9Sstevel@tonic-gate int bits;
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate KMALLOC(ipe, iphtent_t *);
3067c478bd9Sstevel@tonic-gate if (ipe == NULL)
3077c478bd9Sstevel@tonic-gate return -1;
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate bcopy((char *)ipeo, (char *)ipe, sizeof(*ipe));
3107663b816Sml #ifdef USE_INET6
3117663b816Sml if (ipe->ipe_family == AF_INET6) {
3127663b816Sml bits = count6bits((u_32_t *)ipe->ipe_mask.in6_addr8);
3137663b816Sml hv = IPE_HASH_FN(sum4((uint32_t *)ipe->ipe_addr.in6_addr8),
3147663b816Sml sum4((uint32_t *)ipe->ipe_mask.in6_addr8),
3157663b816Sml iph->iph_size);
3167663b816Sml } else
3177663b816Sml #endif
3187663b816Sml if (ipe->ipe_family == AF_INET)
3197663b816Sml {
3207663b816Sml ipe->ipe_addr.in4_addr &= ipe->ipe_mask.in4_addr;
3217663b816Sml ipe->ipe_addr.in4_addr = ntohl(ipe->ipe_addr.in4_addr);
3227663b816Sml bits = count4bits(ipe->ipe_mask.in4_addr);
3237663b816Sml ipe->ipe_mask.in4_addr = ntohl(ipe->ipe_mask.in4_addr);
3247663b816Sml
3257663b816Sml hv = IPE_HASH_FN(ipe->ipe_addr.in4_addr, ipe->ipe_mask.in4_addr,
3267663b816Sml iph->iph_size);
3277663b816Sml } else
3287663b816Sml return -1;
3297c478bd9Sstevel@tonic-gate
330f4b3ec61Sdh ipe->ipe_ref = 1;
3317c478bd9Sstevel@tonic-gate ipe->ipe_next = iph->iph_table[hv];
3327c478bd9Sstevel@tonic-gate ipe->ipe_pnext = iph->iph_table + hv;
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate if (iph->iph_table[hv] != NULL)
3357c478bd9Sstevel@tonic-gate iph->iph_table[hv]->ipe_pnext = &ipe->ipe_next;
3367c478bd9Sstevel@tonic-gate iph->iph_table[hv] = ipe;
337f4b3ec61Sdh
338f4b3ec61Sdh ipe->ipe_snext = iph->iph_list;
339f4b3ec61Sdh ipe->ipe_psnext = &iph->iph_list;
340f4b3ec61Sdh if (ipe->ipe_next != NULL)
341f4b3ec61Sdh ipe->ipe_next->ipe_psnext = &ipe->ipe_snext;
342f4b3ec61Sdh iph->iph_list = ipe;
343f4b3ec61Sdh
3447663b816Sml #ifdef USE_INET6
3457663b816Sml if (ipe->ipe_family == AF_INET6) {
3467663b816Sml if ((bits >= 0) && (bits != 128))
3477663b816Sml if (bits >= 96)
3487663b816Sml iph->iph_masks[0] |= 1 << (bits - 96);
3497663b816Sml else if (bits >= 64)
3507663b816Sml iph->iph_masks[1] |= 1 << (bits - 64);
3517663b816Sml else if (bits >= 32)
3527663b816Sml iph->iph_masks[2] |= 1 << (bits - 32);
3537663b816Sml else
3547663b816Sml iph->iph_masks[3] |= 1 << bits;
3557663b816Sml
3567663b816Sml } else
3577663b816Sml #endif
3587663b816Sml {
3597663b816Sml if ((bits >= 0) && (bits != 32))
3607663b816Sml iph->iph_masks[3] |= 1 << bits;
3617663b816Sml }
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate switch (iph->iph_type & ~IPHASH_ANON)
3647c478bd9Sstevel@tonic-gate {
3657c478bd9Sstevel@tonic-gate case IPHASH_GROUPMAP :
3667c478bd9Sstevel@tonic-gate ipe->ipe_ptr = fr_addgroup(ipe->ipe_group, NULL,
3677c478bd9Sstevel@tonic-gate iph->iph_flags, IPL_LOGIPF,
368f4b3ec61Sdh ifs->ifs_fr_active, ifs);
3697c478bd9Sstevel@tonic-gate break;
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate default :
3727c478bd9Sstevel@tonic-gate ipe->ipe_ptr = NULL;
3737c478bd9Sstevel@tonic-gate ipe->ipe_value = 0;
3747c478bd9Sstevel@tonic-gate break;
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate
377f4b3ec61Sdh ifs->ifs_ipf_nhtnodes[iph->iph_unit]++;
3787663b816Sml
3797c478bd9Sstevel@tonic-gate return 0;
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate * Delete an entry from a hash table.
3857c478bd9Sstevel@tonic-gate */
fr_delhtent(iph,ipe,ifs)386f4b3ec61Sdh int fr_delhtent(iph, ipe, ifs)
3877c478bd9Sstevel@tonic-gate iphtable_t *iph;
3887c478bd9Sstevel@tonic-gate iphtent_t *ipe;
389f4b3ec61Sdh ipf_stack_t *ifs;
3907c478bd9Sstevel@tonic-gate {
391f4b3ec61Sdh if (ipe->ipe_ref != 1)
3927c478bd9Sstevel@tonic-gate return EBUSY;
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate
3957c478bd9Sstevel@tonic-gate *ipe->ipe_pnext = ipe->ipe_next;
3967c478bd9Sstevel@tonic-gate if (ipe->ipe_next != NULL)
3977c478bd9Sstevel@tonic-gate ipe->ipe_next->ipe_pnext = ipe->ipe_pnext;
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate switch (iph->iph_type & ~IPHASH_ANON)
4007c478bd9Sstevel@tonic-gate {
4017c478bd9Sstevel@tonic-gate case IPHASH_GROUPMAP :
4027c478bd9Sstevel@tonic-gate if (ipe->ipe_group != NULL)
403f4b3ec61Sdh fr_delgroup(ipe->ipe_group, IPL_LOGIPF,
404f4b3ec61Sdh ifs->ifs_fr_active, ifs);
4057c478bd9Sstevel@tonic-gate break;
4067c478bd9Sstevel@tonic-gate
4077c478bd9Sstevel@tonic-gate default :
4087c478bd9Sstevel@tonic-gate ipe->ipe_ptr = NULL;
4097c478bd9Sstevel@tonic-gate ipe->ipe_value = 0;
4107c478bd9Sstevel@tonic-gate break;
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate
4137c478bd9Sstevel@tonic-gate KFREE(ipe);
4147c478bd9Sstevel@tonic-gate
415f4b3ec61Sdh ifs->ifs_ipf_nhtnodes[iph->iph_unit]--;
416f4b3ec61Sdh
4177c478bd9Sstevel@tonic-gate return 0;
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate
4207c478bd9Sstevel@tonic-gate
fr_iphmfindgroup(tptr,version,aptr,ifs)421f4b3ec61Sdh void *fr_iphmfindgroup(tptr, version, aptr, ifs)
422ab25eeb5Syz void *tptr;
4237663b816Sml int version;
424ab25eeb5Syz void *aptr;
425f4b3ec61Sdh ipf_stack_t *ifs;
4267c478bd9Sstevel@tonic-gate {
4277663b816Sml i6addr_t *addr;
4287c478bd9Sstevel@tonic-gate iphtable_t *iph;
4297c478bd9Sstevel@tonic-gate iphtent_t *ipe;
4307c478bd9Sstevel@tonic-gate void *rval;
4317c478bd9Sstevel@tonic-gate
4327663b816Sml if ((version != 4)
4337663b816Sml #ifdef USE_INET6
4347663b816Sml && (version != 6)
4357663b816Sml #endif
4367663b816Sml )
4377663b816Sml return NULL;
4387663b816Sml
439f4b3ec61Sdh READ_ENTER(&ifs->ifs_ip_poolrw);
4407c478bd9Sstevel@tonic-gate iph = tptr;
4417c478bd9Sstevel@tonic-gate addr = aptr;
4427c478bd9Sstevel@tonic-gate
4437663b816Sml #ifdef USE_INET6
4447663b816Sml if (version == 6)
4457663b816Sml ipe = fr_iphmfind6(iph, &addr->in6);
4467663b816Sml else
4477663b816Sml #endif
4487663b816Sml if (version == 4)
4497663b816Sml ipe = fr_iphmfind(iph, &addr->in4);
4507663b816Sml else
4517663b816Sml ipe = NULL;
4527c478bd9Sstevel@tonic-gate if (ipe != NULL)
4537c478bd9Sstevel@tonic-gate rval = ipe->ipe_ptr;
4547c478bd9Sstevel@tonic-gate else
4557c478bd9Sstevel@tonic-gate rval = NULL;
456f4b3ec61Sdh RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
4577c478bd9Sstevel@tonic-gate return rval;
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate
461ab25eeb5Syz /* ------------------------------------------------------------------------ */
462ab25eeb5Syz /* Function: fr_iphmfindip */
463ab25eeb5Syz /* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */
464ab25eeb5Syz /* Parameters: tptr(I) - pointer to the pool to search */
465ab25eeb5Syz /* version(I) - IP protocol version (4 or 6) */
466ab25eeb5Syz /* aptr(I) - pointer to address information */
467*de22af4eSJohn Ojemann /* fin - pointer to packet information */
468*de22af4eSJohn Ojemann /* ifs - ipf stack instance */
469ab25eeb5Syz /* */
470ab25eeb5Syz /* Search the hash table for a given address and return a search result. */
471ab25eeb5Syz /* ------------------------------------------------------------------------ */
fr_iphmfindip(tptr,version,aptr,fin,ifs)472*de22af4eSJohn Ojemann int fr_iphmfindip(tptr, version, aptr, fin, ifs)
4737c478bd9Sstevel@tonic-gate void *tptr, *aptr;
4747c478bd9Sstevel@tonic-gate int version;
475*de22af4eSJohn Ojemann fr_info_t *fin;
476f4b3ec61Sdh ipf_stack_t *ifs;
4777c478bd9Sstevel@tonic-gate {
4787663b816Sml i6addr_t *addr;
4797c478bd9Sstevel@tonic-gate iphtable_t *iph;
4807c478bd9Sstevel@tonic-gate iphtent_t *ipe;
4817c478bd9Sstevel@tonic-gate int rval;
4827c478bd9Sstevel@tonic-gate
483ab25eeb5Syz if ((version != 4)
484ab25eeb5Syz #ifdef USE_INET6
485ab25eeb5Syz && (version != 6)
486ab25eeb5Syz #endif
487ab25eeb5Syz )
488ab25eeb5Syz return -1;
489ab25eeb5Syz
4907c478bd9Sstevel@tonic-gate if (tptr == NULL || aptr == NULL)
491ab25eeb5Syz return -1;
4927c478bd9Sstevel@tonic-gate
4937c478bd9Sstevel@tonic-gate iph = tptr;
4947c478bd9Sstevel@tonic-gate addr = aptr;
4957c478bd9Sstevel@tonic-gate
496f4b3ec61Sdh READ_ENTER(&ifs->ifs_ip_poolrw);
4977663b816Sml #ifdef USE_INET6
4987663b816Sml if (version == 6)
4997663b816Sml ipe = fr_iphmfind6(iph, &addr->in6);
5007663b816Sml else
5017663b816Sml #endif
5027663b816Sml if (version == 4)
5037663b816Sml ipe = fr_iphmfind(iph, &addr->in4);
5047663b816Sml else
5057663b816Sml ipe = NULL;
506*de22af4eSJohn Ojemann if (ipe != NULL) {
507*de22af4e