1 /****************************************************************************
2 *
3 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4 * Copyright (C) 2003-2013 Sourcefire, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License Version 2 as
8 * published by the Free Software Foundation. You may not use, modify or
9 * distribute this program under any other version of the GNU General
10 * Public License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 ****************************************************************************/
22
23 /*
24 sfhashfcn.c
25
26 Each hash table must allocate it's own SFGHASH struct, this is because
27 sfghash_new uses the number of rows in the hash table to modulo the random
28 values.
29
30 Updates:
31
32 8/31/2006 - man - changed to use sfprimetable.c
33 */
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include "sf_types.h"
40
41
42 #ifndef MODULUS_HASH
43 # include "snort.h"
44 #endif
45
46 #include "sfhashfcn.h"
47 #include "sfprimetable.h"
48
49
sfhashfcn_new(int m)50 SFHASHFCN * sfhashfcn_new( int m )
51 {
52 SFHASHFCN * p;
53 static int one=1;
54
55 if( one ) /* one time init */
56 {
57 srand( (unsigned) time(0) );
58 one = 0;
59 }
60
61 // This can make all of the hashing static for testing.
62 //#define rand() 0
63
64 p = (SFHASHFCN*) calloc( 1,sizeof(SFHASHFCN) );
65 if( !p )
66 return 0;
67
68 #ifndef MODULUS_HASH
69 #ifndef DYNAMIC_PREPROC_CONTEXT
70 if (ScStaticHash())
71 {
72 sfhashfcn_static(p);
73 }
74 else
75 #endif
76 #endif
77 {
78 p->seed = sf_nearest_prime( (rand()%m)+3191 );
79 p->scale = sf_nearest_prime( (rand()%m)+709 );
80 p->hardener = (rand()*rand()) + 133824503;
81 }
82
83 p->hash_fcn = &sfhashfcn_hash;
84 p->keycmp_fcn = &memcmp;
85
86 return p;
87 }
88
sfhashfcn_free(SFHASHFCN * p)89 void sfhashfcn_free( SFHASHFCN * p )
90 {
91 if( p )
92 {
93 free( p);
94 }
95 }
96
sfhashfcn_static(SFHASHFCN * p)97 void sfhashfcn_static( SFHASHFCN * p )
98 {
99 p->seed = 3193;
100 p->scale = 719;
101 p->hardener = 133824503;
102 }
103
sfhashfcn_hash(SFHASHFCN * p,unsigned char * d,int n)104 unsigned sfhashfcn_hash( SFHASHFCN * p, unsigned char *d, int n )
105 {
106 unsigned hash = p->seed;
107 while( n )
108 {
109 hash *= p->scale;
110 hash += *d++;
111 n--;
112 }
113 return hash ^ p->hardener;
114 }
115
116 /**
117 * Make sfhashfcn use a separate set of operators for the backend.
118 *
119 * @param h sfhashfcn ptr
120 * @param hash_fcn user specified hash function
121 * @param keycmp_fcn user specified key comparisoin function
122 */
sfhashfcn_set_keyops(SFHASHFCN * h,unsigned (* hash_fcn)(SFHASHFCN * p,unsigned char * d,int n),int (* keycmp_fcn)(const void * s1,const void * s2,size_t n))123 int sfhashfcn_set_keyops( SFHASHFCN *h,
124 unsigned (*hash_fcn)( SFHASHFCN * p,
125 unsigned char *d,
126 int n),
127 int (*keycmp_fcn)( const void *s1,
128 const void *s2,
129 size_t n))
130 {
131 if(h && hash_fcn && keycmp_fcn)
132 {
133 h->hash_fcn = hash_fcn;
134 h->keycmp_fcn = keycmp_fcn;
135
136 return 0;
137 }
138
139 return -1;
140 }
141
142