"Fossies" - the Fresh Open Source Software Archive 
Member "snort-2.9.17/tools/u2streamer/Unified2File.c" (16 Oct 2020, 11371 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "Unified2File.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.9.16.1_vs_2.9.17.
1
2 /* System includes */
3 #include <sys/types.h>
4 #ifdef LINUX
5 #include <stdint.h>
6 #endif
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <netinet/in.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <fcntl.h>
17
18 /* Sourcefire includes */
19 #include <sf_error.h>
20 #include <TimestampedFile.h>
21
22 /* Local includes */
23 #include "Unified2.h"
24 #include "Unified2File.h"
25
26 #define U2FILE_STATUS_NOT_READY 0
27 #define U2FILE_STATUS_HEADER_READY 1
28 #define U2FILE_STATUS_HEADER_PARTIAL 2
29 #define U2FILE_STATUS_EXTENDED_HEADER_READY 3
30 #define U2FILE_STATUS_EXTENDED_HEADER_PARTIAL 4
31 #define U2FILE_STATUS_DATA_READY 5
32 #define U2FILE_STATUS_DATA_PARTIAL 6
33
34 #ifndef MAX_U2_MESSAGE
35 #define MAX_U2_MESSAGE (16*1024*1024)
36 #endif
37 #define U2R_EXTENDED_HEADER_BIT 0x80000000
38
39
40 /* Unified2 File API **********************************************************/
41 int Unified2File_Open(char *filepath, Unified2File **u2_file)
42 {
43 Unified2File *tmp;
44
45 if(!filepath || !u2_file)
46 return SF_EINVAL;
47
48 if(!(tmp = (Unified2File *)calloc(1, sizeof(Unified2File))))
49 {
50 fprintf(stderr, "Out of memory (wanted %zu bytes)", sizeof(Unified2File));
51 return SF_ENOMEM;
52 }
53
54 tmp->fd = -1;
55 tmp->read_status = U2FILE_STATUS_HEADER_READY;
56 tmp->read_errno = 0;
57 tmp->read_offset = 0;
58 tmp->u2_record = NULL;
59
60 if((tmp->fd = open(filepath, O_RDONLY)) == -1)
61 {
62 fprintf(stderr, "Unable to open file '%s': %s",
63 filepath, strerror(errno));
64 free(tmp);
65 return SF_EOPEN; /* XXX better return code */
66 }
67
68 *u2_file = tmp;
69
70 return SF_SUCCESS;
71 }
72
73 int Unified2File_Close(Unified2File *u2_file)
74 {
75 if(!u2_file)
76 return SF_EINVAL;
77
78 if(u2_file->u2_record)
79 Unified2Record_Destroy(u2_file->u2_record);
80 u2_file->u2_record = NULL;
81
82 if(u2_file->fd != -1)
83 close(u2_file->fd);
84 u2_file->fd = -1;
85
86 u2_file->read_status = 0;
87
88 free(u2_file);
89
90 return SF_SUCCESS;
91 }
92
93
94 int Unified2File_Read(Unified2File *u2_file, Unified2Record **u2_record)
95 {
96 ssize_t bytes_read;
97 ssize_t bytes_wanted;
98 int error_count = 0;
99
100 if(!u2_file || !u2_record)
101 return SF_EINVAL;
102
103 if(u2_file->read_status == U2FILE_STATUS_NOT_READY)
104 return SF_EREAD;
105
106 /* allocate a new record */
107 if(!u2_file->u2_record)
108 {
109 /* XXX we should check that we are in the HEADER_READY state */
110 if(!(u2_file->u2_record = (Unified2Record *)calloc(1,
111 sizeof(Unified2Record))))
112 {
113 fprintf(stderr, "Out of memory (wanted %zu bytes)",
114 sizeof(Unified2Record));
115 return SF_ENOMEM;
116 }
117 u2_file->read_offset = 0;
118 u2_file->read_status = U2FILE_STATUS_HEADER_READY;
119 }
120
121 if(u2_file->read_status == U2FILE_STATUS_HEADER_READY
122 || u2_file->read_status == U2FILE_STATUS_HEADER_PARTIAL)
123 {
124 read_again:
125 /* read the header */
126 bytes_wanted = sizeof(Serial_Unified2_Header);
127 bytes_read = read(u2_file->fd,
128 ((u_int8_t *)&u2_file->s_u2_hdr) + u2_file->read_offset,
129 bytes_wanted - u2_file->read_offset);
130
131 /* end of file **************************/
132 if(bytes_read == 0)
133 {
134 if(u2_file->read_status == U2FILE_STATUS_HEADER_PARTIAL)
135 {
136 fprintf(stderr, "End of file within header");
137
138 if(errno) return SF_EREAD_TRUNCATED;
139 return SF_EREAD_PARTIAL;
140 }
141
142 //fprintf(stderr, "End of file on record boundary");
143
144 return SF_END_OF_FILE;
145 }
146 /* Read error **************************/
147 if(bytes_read == -1)
148 {
149 /* read error */
150 fprintf(stderr, "Read error: %s",
151 strerror(errno));
152 u2_file->read_errno = errno;
153 u2_file->read_status = U2FILE_STATUS_NOT_READY;
154 return SF_EREAD;
155 }
156
157 /* check for partial read *************/
158 if(bytes_read + u2_file->read_offset < bytes_wanted)
159 {
160 u2_file->read_offset += bytes_read;
161 u2_file->read_status = U2FILE_STATUS_HEADER_PARTIAL;
162 fprintf(stderr, "Partial header read (%u of %zu bytes)",
163 u2_file->read_offset, bytes_wanted);
164 return SF_EREAD_PARTIAL;
165 }
166
167 /* basic header read is complete */
168
169 /* process basic header data */
170 u2_file->u2_record->type = ntohl(u2_file->s_u2_hdr.type);
171 u2_file->u2_record->length = ntohl(u2_file->s_u2_hdr.length);
172 /* XXX we have enough info now to allocate storage for the data */
173
174 if(!u2_file->u2_record->length || (u2_file->u2_record->length >= MAX_U2_MESSAGE))
175 {
176 /* Seek back to where we started, in case we want to try again */
177 off_t rval = lseek(u2_file->fd, (0 - bytes_read), SEEK_CUR);
178 fprintf(stderr, "Seek backwards %zu bytes, seek returns %ld", bytes_read, rval);
179
180 error_count++;
181 usleep(100);
182 if (error_count >= 10)
183 {
184 fprintf(stderr, "Unsupported length: Tried to read (%d bytes - allowed %d) at offset %ld Type %u",
185 u2_file->u2_record->length,
186 MAX_U2_MESSAGE,
187 rval,
188 u2_file->u2_record->type & ~U2R_EXTENDED_HEADER_BIT);
189 return SF_EBADLEN;
190 }
191 else
192 {
193 goto read_again;
194 }
195 }
196
197 /* check to see if we have an extended header */
198 if(u2_file->u2_record->type & U2R_EXTENDED_HEADER_BIT)
199 {
200 u2_file->read_status = U2FILE_STATUS_EXTENDED_HEADER_READY;
201 u2_file->u2_record->type &= ~U2R_EXTENDED_HEADER_BIT;
202 }
203 else
204 {
205 u2_file->u2_record->timestamp = 0;
206 u2_file->checksum = 0;
207 u2_file->read_status = U2FILE_STATUS_DATA_READY;
208 }
209
210 u2_file->read_offset = 0;
211 }
212 if(error_count > 0)
213 {
214 fprintf(stderr, "Bogus corrupt file, re-read %d times before file valid.", error_count);
215 }
216
217 if(u2_file->read_status == U2FILE_STATUS_EXTENDED_HEADER_READY
218 || u2_file->read_status == U2FILE_STATUS_EXTENDED_HEADER_PARTIAL)
219 {
220 /* read the header extensions */
221 bytes_wanted = sizeof(Serial_Unified2HeaderExtension);
222 bytes_read = read(u2_file->fd,
223 ((u_int8_t *)&u2_file->s_u2_hdr_ext) + u2_file->read_offset,
224 bytes_wanted - u2_file->read_offset);
225
226 /* end of file **************************/
227 if(bytes_read == 0)
228 {
229 fprintf(stderr, "End of file within header");
230
231 if(errno) return SF_EREAD_TRUNCATED;
232 return SF_EREAD_PARTIAL;
233 }
234 /* Read error **************************/
235 if(bytes_read == -1)
236 {
237 /* read error */
238 fprintf(stderr, "Read error: %s",
239 strerror(errno));
240 u2_file->read_errno = errno;
241 u2_file->read_status = U2FILE_STATUS_NOT_READY;
242 return SF_EREAD;
243 }
244
245 /* check for partial read *************/
246 if(bytes_read + u2_file->read_offset < bytes_wanted)
247 {
248 u2_file->read_offset += bytes_read;
249 u2_file->read_status = U2FILE_STATUS_EXTENDED_HEADER_PARTIAL;
250 fprintf(stderr, "Partial header read (%u of %zu bytes)",
251 u2_file->read_offset, bytes_wanted);
252 return SF_EREAD_PARTIAL;
253 }
254
255 /* header extension read complete */
256 /* process header extenstion data */
257 //VLAD we do have an extended header?
258 u2_file->u2_record->timestamp = ntohl(u2_file->s_u2_hdr_ext.timestamp);
259 u2_file->checksum = ntohl(u2_file->s_u2_hdr_ext.checksum);
260
261 u2_file->read_status = U2FILE_STATUS_DATA_READY;
262 u2_file->read_offset = 0;
263 }
264
265 /* we should not have any of these, but just in case */
266 if(u2_file->u2_record->length == 0)
267 {
268 u2_file->read_offset = 0;
269 u2_file->read_status = U2FILE_STATUS_HEADER_READY;
270 *u2_record = u2_file->u2_record;
271 u2_file->u2_record = NULL;
272 return SF_SUCCESS;
273 }
274
275 /* XXX some other length sanity checking may be desirable */
276
277 /* read the actual data ***********************/
278 if(u2_file->read_status == U2FILE_STATUS_DATA_READY
279 || u2_file->read_status == U2FILE_STATUS_DATA_PARTIAL)
280 {
281 /* allocate memory if we have not done so yet */
282 if(!u2_file->u2_record->data)
283 {
284 if(!u2_file->u2_record->length || (u2_file->u2_record->length >= MAX_U2_MESSAGE))
285 {
286 fprintf(stderr, "Unsupported length: Tried to read (%d bytes - allowed %d) Type %u",
287 u2_file->u2_record->length,
288 MAX_U2_MESSAGE,
289 u2_file->u2_record->type & ~U2R_EXTENDED_HEADER_BIT);
290 return SF_EBADLEN;
291 }
292
293 /* allocate the buffer (we could do this earlier) */
294 if(!(u2_file->u2_record->data = calloc(u2_file->u2_record->length,sizeof(uint8_t))))
295 {
296 fprintf(stderr,"Out of memory (wanted %u bytes)",u2_file->u2_record->length);
297 return SF_ENOMEM;
298 /* Amazingly enough, this is not a fatal error. if the user
299 * frees up some memory, we can try again
300 */
301 }
302 }
303
304 /* read the actual data */
305 bytes_wanted = u2_file->u2_record->length;
306 bytes_read = read(u2_file->fd,
307 ((u_int8_t *)u2_file->u2_record->data) + u2_file->read_offset,
308 bytes_wanted - u2_file->read_offset);
309
310 /* end of file **************************/
311 if(bytes_read == 0)
312 {
313 fprintf(stderr, "End of file reading data");
314
315 if(errno) return SF_EREAD_TRUNCATED;
316 return SF_EREAD_PARTIAL;
317 }
318 /* Read error **************************/
319 if(bytes_read == -1)
320 {
321 /* read error */
322 fprintf(stderr, "Read error: %s",
323 strerror(errno));
324 u2_file->read_errno = errno;
325 u2_file->read_status = U2FILE_STATUS_NOT_READY;
326 return SF_EREAD;
327 }
328
329 /* check for partial read *************/
330 if(bytes_read + u2_file->read_offset < bytes_wanted)
331 {
332 u2_file->read_offset += bytes_read;
333 u2_file->read_status = U2FILE_STATUS_DATA_PARTIAL;
334 fprintf(stderr, "Partial header read (%u of %zu bytes)",
335 u2_file->read_offset, bytes_wanted);
336 return SF_EREAD_PARTIAL;
337 }
338
339 /* data read complete */
340
341 if(u2_file->checksum != 0)
342 {
343 /* XXX validation code goes here */
344 }
345
346 u2_file->read_offset = 0;
347 u2_file->read_status = U2FILE_STATUS_HEADER_READY;
348 *u2_record = u2_file->u2_record;
349 u2_file->u2_record = NULL;
350 return SF_SUCCESS;
351 }
352
353 /* We should never get here */
354 return SF_EINVAL;
355 }
356