1 /*
2 ** $Id$
3 **
4 ** bitopt_funcs.h
5 **
6 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
7 ** Copyright (C) 2002-2013 Sourcefire, Inc.
8 ** Dan Roelker <droelker@sourcefire.com>
9 ** Marc Norton <mnorton@sourcefire.com>
10 **
11 ** This program is free software; you can redistribute it and/or modify
12 ** it under the terms of the GNU General Public License Version 2 as
13 ** published by the Free Software Foundation. You may not use, modify or
14 ** distribute this program under any other version of the GNU General
15 ** Public License.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 **
26 ** NOTES
27 ** 5.15.02 - Initial Source Code. Norton/Roelker
28 ** 5.23.02 - Moved bitop functions to bitop.h to inline. Norton/Roelker
29 ** 1.21.04 - Added static initialization. Roelker
30 ** 9.13.05 - Separated type and inline func definitions. Sturges
31 **
32 */
33
34 #ifndef _BITOP_FUNCS_H
35 #define _BITOP_FUNCS_H
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44
45 #include "snort_debug.h"
46 #include "bitop.h"
47
48 /*
49 ** NAME
50 ** boInitStaticBITOP::
51 */
52 /**
53 ** This function is for use if you handle the bitop buffer allocation
54 ** yourself. Just pass in the char array and the number of bytes the array
55 ** is and this function sets up the structure for you.
56 **
57 ** @retval int
58 **
59 ** @return 0 successful
60 ** @return !0 failed
61 */
boInitStaticBITOP(BITOP * BitOp,int iBytes,unsigned char * buf)62 static inline int boInitStaticBITOP(BITOP *BitOp,int iBytes,unsigned char *buf)
63 {
64 if(iBytes < 1 || !buf || !BitOp)
65 return 1;
66
67 BitOp->pucBitBuffer = buf;
68 BitOp->uiBitBufferSize = (unsigned int)iBytes;
69 BitOp->uiMaxBits = (unsigned int)(iBytes << 3);
70
71 memset(buf, 0x00, iBytes);
72
73 return 0;
74 }
75
76 /*
77 **
78 ** NAME
79 ** boInitBITOP
80 **
81 ** DESCRIPTION
82 ** Initializes the BITOP structure for use.
83 **
84 ** NOTE:
85 ** BITOP structure must be zeroed to avoid misinterpretation
86 ** of initialization.
87 **
88 ** FORMAL INPUTS
89 ** BITOP * - the structure to initialize
90 ** int - the number of bit positions to hold.
91 **
92 ** FORMAL OUTPUTS
93 ** int - 0 if successful, 1 if failed.
94 **
95 */
boInitBITOP(BITOP * BitOp,int iBytes)96 static inline int boInitBITOP(BITOP *BitOp, int iBytes)
97 {
98 int iSize;
99
100 /*
101 ** Sanity check for size
102 */
103 if((iBytes < 1) || (BitOp == NULL))
104 {
105 return 1;
106 }
107
108 /*
109 ** Check for already initialized buffer, and
110 ** if it is already initialized then we return that it
111 ** is initialized.
112 */
113 if(BitOp->pucBitBuffer)
114 {
115 return 0;
116 }
117
118 iSize = iBytes << 3;
119
120 BitOp->pucBitBuffer = (unsigned char *)calloc(1, iBytes);
121 if(BitOp->pucBitBuffer == NULL)
122 {
123 return 1;
124 }
125
126 BitOp->uiBitBufferSize = (unsigned int)iBytes;
127 BitOp->uiMaxBits = (unsigned int)iSize;
128
129 return 0;
130 }
131
132 /*
133 **
134 ** NAME
135 ** boResetBITOP
136 **
137 ** DESCRIPTION
138 ** This resets the bit buffer so that it can be used again.
139 **
140 ** FORMAL INPUTS
141 ** BITOP * - structure to reset
142 **
143 ** FORMAL OUTPUT
144 ** int - 0 if successful, 1 if failed.
145 **
146 */
boResetBITOP(BITOP * BitOp)147 static inline int boResetBITOP(BITOP *BitOp)
148 {
149 if (BitOp == NULL)
150 return 1;
151
152 memset(BitOp->pucBitBuffer, 0x00, BitOp->uiBitBufferSize);
153 return 0;
154 }
155
156 /*
157 **
158 ** NAME
159 ** boSetAllBits
160 **
161 ** DESCRIPTION
162 ** This resets the bit buffer to all 1's so that it can be used again.
163 **
164 ** FORMAL INPUTS
165 ** BITOP * - structure to reset
166 **
167 ** FORMAL OUTPUT
168 ** int - 0 if successful, 1 if failed.
169 **
170 */
boSetAllBits(BITOP * BitOp)171 static inline int boSetAllBits(BITOP *BitOp)
172 {
173 if (BitOp == NULL)
174 return 1;
175
176 memset(BitOp->pucBitBuffer, 0xff, BitOp->uiBitBufferSize);
177 return 0;
178 }
179
180 /*
181 **
182 ** NAME
183 ** boSetBit
184 **
185 ** DESCRIPTION
186 ** Set the bit in the specified position within the bit buffer.
187 **
188 ** FORMAL INPUTS
189 ** BITOP * - the structure with the bit buffer
190 ** int - the position to set within the bit buffer
191 **
192 ** FORMAL OUTPUTS
193 ** int - 0 if the bit was set, 1 if there was an error.
194 **
195 */
boSetBit(BITOP * BitOp,unsigned int uiPos)196 static inline int boSetBit(BITOP *BitOp, unsigned int uiPos)
197 {
198 unsigned char mask;
199
200 /*
201 ** Sanity Check while setting bits
202 */
203 if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos))
204 return 1;
205
206 mask = (unsigned char)( 0x80 >> (uiPos & 7));
207
208 BitOp->pucBitBuffer[uiPos >> 3] |= mask;
209
210 return 0;
211 }
212 /*
213 **
214 ** NAME
215 ** boIsBitSet
216 **
217 ** DESCRIPTION
218 ** Checks for the bit set in iPos of bit buffer.
219 **
220 ** FORMAL INPUTS
221 ** BITOP * - structure that holds the bit buffer
222 ** int - the position number in the bit buffer
223 **
224 ** FORMAL OUTPUTS
225 ** int - 0 if bit not set, 1 if bit is set.
226 **
227 */
boIsBitSet(BITOP * BitOp,unsigned int uiPos)228 static inline int boIsBitSet(BITOP *BitOp, unsigned int uiPos)
229 {
230 unsigned char mask;
231
232 /*
233 ** Sanity Check while setting bits
234 */
235 if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos))
236 return 0;
237
238 mask = (unsigned char)(0x80 >> (uiPos & 7));
239
240 return (mask & BitOp->pucBitBuffer[uiPos >> 3]);
241 }
242
243 /*
244 **
245 ** NAME
246 ** boClearBit
247 **
248 ** DESCRIPTION
249 ** Clear the bit in the specified position within the bit buffer.
250 **
251 ** FORMAL INPUTS
252 ** BITOP * - the structure with the bit buffer
253 ** int - the position to clear within the bit buffer
254 **
255 ** FORMAL OUTPUTS
256 ** int - 0 if the bit was cleared, 1 if there was an error.
257 **
258 */
boClearBit(BITOP * BitOp,unsigned int uiPos)259 static inline void boClearBit(BITOP *BitOp, unsigned int uiPos)
260 {
261 unsigned char mask;
262
263 /*
264 ** Sanity Check while clearing bits
265 */
266 if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos))
267 return;
268
269 mask = (unsigned char)(0x80 >> (uiPos & 7));
270
271 BitOp->pucBitBuffer[uiPos >> 3] &= ~mask;
272 }
273
274 /*
275 **
276 ** NAME
277 ** boClearByte
278 **
279 ** DESCRIPTION
280 ** Clear the byte in the specified position within the bit buffer.
281 **
282 ** FORMAL INPUTS
283 ** BITOP * - the structure with the bit buffer
284 ** int - the position to clear within the bit buffer
285 **
286 ** FORMAL OUTPUTS
287 ** int - 0 if the byte was cleared, 1 if there was an error.
288 **
289 */
boClearByte(BITOP * BitOp,unsigned int uiPos)290 static inline void boClearByte(BITOP *BitOp, unsigned int uiPos)
291 {
292 /*
293 ** Sanity Check while clearing bytes
294 */
295 if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos))
296 return;
297
298 BitOp->pucBitBuffer[uiPos >> 3] = 0;
299 }
300
301 /*
302 **
303 ** NAME
304 ** boFreeBITOP
305 **
306 ** DESCRIPTION
307 ** Frees memory created by boInitBITOP - specifically
308 ** BitOp->pucBitBuffer
309 **
310 ** NOTE:
311 ** !!! ONLY USE THIS FUNCTION IF YOU USED boInitBITOP !!!
312 **
313 ** FORMAL INPUTS
314 ** BITOP * - the structure initially passed to boInitBITOP
315 **
316 ** FORMAL OUTPUTS
317 ** void function
318 **
319 **/
boFreeBITOP(BITOP * BitOp)320 static inline void boFreeBITOP(BITOP *BitOp)
321 {
322 if((BitOp == NULL) || (BitOp->pucBitBuffer == NULL))
323 return;
324
325 free(BitOp->pucBitBuffer);
326 BitOp->pucBitBuffer = NULL;
327 }
328
329 #endif /* _BITOPT_FUNCS_H_ */
330