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