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