1 /*****
2 *
3 * Copyright (C) 2002-2015 CS-SI. All Rights Reserved.
4 * Author: Yoann Vandoorselaere <yoann.v@prelude-ids.com>
5 *
6 * This file is part of the Prelude library.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *****/
23 
24 #ifndef _LIBPRELUDE_EXTRACT_H
25 #define _LIBPRELUDE_EXTRACT_H
26 
27 #include "prelude-config.h"
28 
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 
33 #ifndef WIN32
34 # include <netinet/in.h>
35 #else
36 # include <winsock2.h>
37 #endif
38 
39 #include "prelude-inttypes.h"
40 
41 
42 #ifdef PRELUDE_ALIGNED_ACCESS
43 
44 #include <string.h> /* for memmove */
45 
46 #ifdef __cplusplus
47  extern "C" {
48 #endif
49 
50 
51 /*
52  * Using memmove make the generated code substencially slower,
53  * we seen difference from 20MB/s to 200MB/s from the memmove version
54  * to this version in doing checksum test.
55  */
56 
57 #ifdef PRELUDE_WORDS_BIGENDIAN
58 # define byte(type, buf, pos) (type) ((const uint8_t *) (buf))[(pos)]
59 #else
60 # define byte(type, buf, pos) (type) ((const uint8_t *) (buf))[sizeof(type) - 1 - (pos)]
61 #endif
62 
63 
prelude_align_uint16(const void * buf)64 static inline uint16_t prelude_align_uint16(const void *buf)
65 {
66         return byte(uint16_t, buf, 0) << 8 | byte(uint16_t, buf, 1);
67 }
68 
69 
70 
71 
prelude_align_int32(const void * buf)72 static inline int32_t prelude_align_int32(const void *buf)
73 {
74         return  byte(int32_t, buf, 0) << 24 | byte(int32_t, buf, 1) << 16 |
75                 byte(int32_t, buf, 2) <<  8 | byte(int32_t, buf, 3);
76 }
77 
78 
79 
prelude_align_uint32(const void * buf)80 static inline uint32_t prelude_align_uint32(const void *buf)
81 {
82         return  byte(uint32_t, buf, 0) << 24 | byte(uint32_t, buf, 1) << 16 |
83                 byte(uint32_t, buf, 2) <<  8 | byte(uint32_t, buf, 3);
84 }
85 
86 
prelude_align_uint64(const void * buf)87 static inline uint64_t prelude_align_uint64(const void *buf)
88 {
89         return  byte(uint64_t, buf, 0) << 56 | byte(uint64_t, buf, 1) << 48 | byte(uint64_t, buf, 2) << 40 |
90                 byte(uint64_t, buf, 3) << 32 | byte(uint64_t, buf, 4) << 24 | byte(uint64_t, buf, 5) << 16 |
91                 byte(uint64_t, buf, 6) <<  8 | byte(uint64_t, buf, 7);
92 }
93 
94 
95 
prelude_align_float(const void * buf)96 static inline float prelude_align_float(const void *buf)
97 {
98         return prelude_align_uint32(buf);
99 }
100 
101 
102 #else
103 
104 #define prelude_align_uint16(x) (*(const uint16_t *) (x))
105 #define prelude_align_int32(x) (*(const int32_t *) (x))
106 #define prelude_align_uint32(x) (*(const uint32_t *) (x))
107 #define prelude_align_uint64(x) (*(const uint64_t *) (x))
108 #define prelude_align_float(x) (*(const float *) (x))
109 
110 #endif
111 
112 #include "prelude-string.h"
113 #include "idmef-time.h"
114 #include "idmef-data.h"
115 
116 
prelude_extract_uint16(const void * buf)117 static inline uint16_t prelude_extract_uint16(const void *buf)
118 {
119         return ntohs(prelude_align_uint16(buf));
120 }
121 
122 
123 
prelude_extract_int32(const void * buf)124 static inline int32_t prelude_extract_int32(const void *buf)
125 {
126         return ntohl(prelude_align_int32(buf));
127 }
128 
129 
130 
prelude_extract_uint32(const void * buf)131 static inline uint32_t prelude_extract_uint32(const void *buf)
132 {
133         return ntohl(prelude_align_uint32(buf));
134 }
135 
136 
137 
prelude_extract_float(const void * buf)138 static inline float prelude_extract_float(const void *buf)
139 {
140         union {
141                 float fval;
142                 uint32_t ival;
143         } val;
144 
145         val.ival = ntohl(prelude_align_uint32(buf));
146 
147         return val.fval;
148 }
149 
150 
151 
prelude_extract_uint64(const void * buf)152 static inline uint64_t prelude_extract_uint64(const void *buf)
153 {
154 #ifdef PRELUDE_WORDS_BIGENDIAN
155 
156         return prelude_align_uint64(buf);
157 
158 #else
159         union {
160                 uint64_t val64;
161                 uint32_t val32[2];
162         } combo_r, combo_w;
163 
164         combo_r.val64 = prelude_align_uint64(buf);
165 
166         combo_w.val32[0] = ntohl(combo_r.val32[1]);
167         combo_w.val32[1] = ntohl(combo_r.val32[0]);
168 
169         return combo_w.val64;
170 #endif
171 }
172 
173 
174 /*
175  * Theses function check the buffer size for safety.
176  */
prelude_extract_uint8_safe(uint8_t * out,const void * buf,size_t len)177 static inline int prelude_extract_uint8_safe(uint8_t *out, const void *buf, size_t len)
178 {
179         if ( len != sizeof(uint8_t) )
180                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_INT8);
181 
182         *out = *(const uint8_t *) buf;
183 
184         return 0;
185 }
186 
187 
prelude_extract_uint16_safe(uint16_t * out,const void * buf,size_t len)188 static inline int prelude_extract_uint16_safe(uint16_t *out, const void *buf, size_t len)
189 {
190         if ( len != sizeof(uint16_t) )
191                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_INT16);
192 
193         *out = prelude_extract_uint16(buf);
194 
195         return 0;
196 }
197 
198 
199 
prelude_extract_uint32_safe(uint32_t * out,const void * buf,size_t len)200 static inline int prelude_extract_uint32_safe(uint32_t *out, const void *buf, size_t len)
201 {
202         if ( len != sizeof(uint32_t) )
203                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_INT32);
204 
205         *out = prelude_extract_uint32(buf);
206 
207         return 0;
208 }
209 
210 
211 
prelude_extract_int32_safe(int32_t * out,const void * buf,size_t len)212 static inline int prelude_extract_int32_safe(int32_t *out, const void *buf, size_t len)
213 {
214         if ( len != sizeof(int32_t) )
215                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_INT32);
216 
217         *out = prelude_extract_int32(buf);
218 
219         return 0;
220 }
221 
222 
223 
prelude_extract_uint64_safe(uint64_t * out,const void * buf,size_t len)224 static inline int prelude_extract_uint64_safe(uint64_t *out, const void *buf, size_t len)
225 {
226         if ( len != sizeof(uint64_t) )
227                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_INT64);
228 
229         *out = prelude_extract_uint64(buf);
230 
231         return 0;
232 }
233 
234 
235 
prelude_extract_float_safe(float * out,const void * buf,size_t len)236 static inline int prelude_extract_float_safe(float *out, const void *buf, size_t len)
237 {
238         if ( len != sizeof(uint32_t) ) /* We pack float as an uint32_t */
239                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_FLOAT);
240 
241         *out = prelude_extract_float(buf);
242 
243         return 0;
244 }
245 
246 
247 
prelude_extract_characters_safe(const char ** out,char * buf,size_t len)248 static inline int prelude_extract_characters_safe(const char **out, char *buf, size_t len)
249 {
250         if ( len < 2 || buf[len - 1] != '\0' )
251                 return prelude_error_make(PRELUDE_ERROR_SOURCE_EXTRACT, PRELUDE_ERROR_INVAL_CHAR);
252 
253         *out = buf;
254 
255         return 0;
256 }
257 
258 #ifdef __cplusplus
259  }
260 #endif
261 
262 #endif /* _LIBPRELUDE_EXTRACT_H */
263