1 /*
2 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 * Copyright (C) 2002-2013 Sourcefire, Inc.
4 * Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
5 * Author: Adam Keeton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License Version 2 as
9 * published by the Free Software Foundation. You may not use, modify or
10 * distribute this program under any other version of the GNU General
11 * Public License.
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
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdio.h>
29
30 #ifndef WIN32
31 #include <ctype.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <errno.h>
35
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #endif
41 #ifdef HAVE_UUID_UUID_H
42 #include<uuid/uuid.h>
43 #endif
44
45 #include "Unified2_common.h"
46
47 #define SUCCESS 314159265
48 #define STEVE -1
49 #define FAILURE STEVE
50
51 #ifndef WIN32
52 #ifndef uint32_t
53 typedef unsigned int uint32_t;
54 typedef unsigned short uint16_t;
55 typedef unsigned char uint8_t;
56 #endif
57 #else
inet_ntop(int family,const void * ip_raw,char * buf,int bufsize)58 static void inet_ntop(int family, const void *ip_raw, char *buf, int bufsize) {
59 int i;
60
61 if(!ip_raw || !buf || !bufsize ||
62 (family != AF_INET && family != AF_INET6) ||
63 /* Make sure if it's IPv6 that the buf is large enough. */
64 /* Need atleast a max of 8 fields of 4 bytes plus 7 for colons in
65 * between. Need 1 more byte for null. */
66 (family == AF_INET6 && bufsize < 8*4 + 7 + 1) ||
67 /* Make sure if it's IPv4 that the buf is large enough. */
68 /* 4 fields of 3 numbers, plus 3 dots and a null byte */
69 (family == AF_INET && bufsize < 3*4 + 4) )
70 {
71 if(buf && bufsize > 0) buf[0] = 0;
72 return;
73 }
74
75 /* 4 fields of at most 3 characters each */
76 if(family == AF_INET) {
77 u_int8_t *p = (u_int8_t*)ip_raw;
78
79 for(i=0; p < ((u_int8_t*)ip_raw) + 4; p++) {
80 i += sprintf(&buf[i], "%d", *p);
81
82 /* If this is the last iteration, this could technically cause one
83 * extra byte to be written past the end. */
84 if(i < bufsize && ((p + 1) < ((u_int8_t*)ip_raw+4)))
85 buf[i] = '.';
86
87 i++;
88 }
89
90 /* Check if this is really just an IPv4 address represented as 6,
91 * in compatible format */
92 #if 0
93 }
94 else if(!field[0] && !field[1] && !field[2]) {
95 unsigned char *p = (unsigned char *)(&ip->ip[12]);
96
97 for(i=0; p < &ip->ip[16]; p++)
98 i += sprintf(&buf[i], "%d.", *p);
99 #endif
100 }
101 else {
102 u_int16_t *p = (u_int16_t*)ip_raw;
103
104 for(i=0; p < ((u_int16_t*)ip_raw) + 8; p++) {
105 i += sprintf(&buf[i], "%04x", ntohs(*p));
106
107 /* If this is the last iteration, this could technically cause one
108 * extra byte to be written past the end. */
109 if(i < bufsize && ((p + 1) < ((u_int16_t*)ip_raw) + 8))
110 buf[i] = ':';
111
112 i++;
113 }
114 }
115 }
116 #endif
117
118 typedef struct _record {
119 uint32_t type;
120 uint32_t length;
121 uint8_t *data;
122 } u2record;
123
124 typedef struct _u2iterator {
125 FILE *file;
126 char *filename;
127 u2record current;
128 } u2iterator;
129
130 static long s_pos = 0, s_off = 0;
131
132 #define TO_IP(x) x >> 24, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff
133
new_iterator(char * filename)134 static u2iterator *new_iterator(char *filename) {
135 FILE *f = fopen(filename, "rb");
136 u2iterator *ret;
137
138 if(!f) {
139 printf("new_iterator: Failed to open file: %s\n\tErrno: %s\n",
140 filename, strerror(errno));
141 return NULL;
142 }
143
144 ret = (u2iterator*)malloc(sizeof(u2iterator));
145
146 if(!ret) {
147 printf("new_iterator: Failed to malloc %lu bytes.\n", (unsigned long)sizeof(u2iterator));
148 fclose(f);
149 return NULL;
150 }
151
152 ret->file = f;
153 ret->filename = strdup(filename);
154 return ret;
155 }
156
free_iterator(u2iterator * it)157 static inline void free_iterator(u2iterator *it) {
158 if(it->file) fclose(it->file);
159 if(it->filename) free(it->filename);
160 if(it) free(it);
161 }
162
get_record(u2iterator * it,u2record * record)163 static int get_record(u2iterator *it, u2record *record) {
164 uint32_t bytes_read;
165 uint8_t *tmp;
166
167 if(!it || !it->file) return FAILURE;
168
169 /* check if the log was rotated */
170 if(feof(it->file)) {
171 /* Get next timestamped file? */
172 puts("Hit the EOF .. and this is not being handled yet.");
173 return FAILURE;
174 }
175
176 if ( s_off )
177 {
178 if (fseek(it->file, s_pos+s_off, SEEK_SET))
179 {
180 puts("Unable to SEEK on current file .. and this is not being handled yet.");
181 return FAILURE;
182 }
183 s_off = 0;
184 }
185
186 /* read type and length */
187 bytes_read = fread(record, 1, sizeof(uint32_t) * 2, it->file);
188 /* But they're in network order! */
189 record->type= ntohl(record->type);
190 record->length= ntohl(record->length);
191
192 //if(record->type == UNIFIED2_PACKET) record->length+=4;
193
194 if(bytes_read == 0)
195 /* EOF */
196 return FAILURE;
197
198 if(bytes_read != sizeof(uint32_t)*2) {
199 puts("get_record: (1) Failed to read all of record.");
200 printf("\tRead %u of %lu bytes\n", bytes_read, (unsigned long)sizeof(uint32_t)*2);
201 return FAILURE;
202 }
203
204 s_pos = ftell(it->file);
205
206 tmp = (uint8_t *)realloc(record->data, record->length);
207
208 if (!tmp)
209 {
210 puts("get_record: (2) Failed to allocate memory.");
211 free(record->data);
212 return FAILURE;
213 }
214
215 record->data = tmp;
216
217 bytes_read = fread(record->data, 1, record->length, it->file);
218
219 if(bytes_read != record->length) {
220 puts("get_record: (3) Failed to read all of record data.");
221 printf("\tRead %u of %u bytes\n", bytes_read, record->length);
222
223 if ( record->type != UNIFIED2_PACKET ||
224 bytes_read < ntohl(((Serial_Unified2Packet*)record->data)->packet_length)
225 )
226 return FAILURE;
227
228 clearerr(it->file);
229 }
230
231 return SUCCESS;
232 }
233
extradata_dump(u2record * record)234 static void extradata_dump(u2record *record) {
235 uint8_t *field, *data;
236 int i;
237 int len = 0;
238 SerialUnified2ExtraData event;
239 Unified2ExtraDataHdr eventHdr;
240 uint32_t ip;
241 char ip6buf[INET6_ADDRSTRLEN+1];
242 struct in6_addr ipAddr;
243
244 memcpy(&eventHdr, record->data, sizeof(Unified2ExtraDataHdr));
245
246 memcpy(&event, record->data + sizeof(Unified2ExtraDataHdr) , sizeof(SerialUnified2ExtraData));
247
248 /* network to host ordering */
249 field = (uint8_t*)&eventHdr;
250 for(i=0; i<2; i++, field+=4) {
251 *(uint32_t*)field = ntohl(*(uint32_t*)field);
252 }
253
254 field = (uint8_t*)&event;
255 for(i=0; i<6; i++, field+=4) {
256 *(uint32_t*)field = ntohl(*(uint32_t*)field);
257 }
258
259
260
261 printf("\n(ExtraDataHdr)\n"
262 "\tevent type: %u\tevent length: %u\n",
263 eventHdr.event_type, eventHdr.event_length);
264
265 printf("\n(ExtraData)\n"
266 "\tsensor id: %u\tevent id: %u\tevent second: %u\n"
267 "\ttype: %u\tdatatype: %u\tbloblength: %u\t",
268 event.sensor_id, event.event_id,
269 event.event_second, event.type,
270 event.data_type, event.blob_length);
271
272 len = event.blob_length - sizeof(event.blob_length) - sizeof(event.data_type);
273
274 switch(event.type)
275 {
276 case EVENT_INFO_XFF_IPV4:
277 memcpy(&ip, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(uint32_t));
278 ip = ntohl(ip);
279 printf("Original Client IP: %u.%u.%u.%u\n",
280 TO_IP(ip));
281 break;
282
283 case EVENT_INFO_XFF_IPV6:
284 memcpy(&ipAddr, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(struct in6_addr));
285 inet_ntop(AF_INET6, &ipAddr, ip6buf, INET6_ADDRSTRLEN);
286 printf("Original Client IP: %s\n",
287 ip6buf);
288 break;
289
290 case EVENT_INFO_GZIP_DATA:
291 printf("GZIP Decompressed Data: %.*s\n",
292 len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
293 break;
294
295 case EVENT_INFO_JSNORM_DATA:
296 printf("Normalized JavaScript Data: %.*s\n",
297 len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
298 break;
299
300 case EVENT_INFO_SMTP_FILENAME:
301 printf("SMTP Attachment Filename: %.*s\n",
302 len,record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
303 break;
304
305 case EVENT_INFO_SMTP_MAILFROM:
306 printf("SMTP MAIL FROM Addresses: %.*s\n",
307 len,record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
308 break;
309
310 case EVENT_INFO_SMTP_RCPTTO:
311 printf("SMTP RCPT TO Addresses: %.*s\n",
312 len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
313 break;
314
315 case EVENT_INFO_SMTP_EMAIL_HDRS:
316 printf("SMTP EMAIL HEADERS: \n%.*s\n",
317 len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
318 break;
319
320 case EVENT_INFO_HTTP_URI:
321 printf("HTTP URI: %.*s\n",
322 len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
323 break;
324
325 case EVENT_INFO_HTTP_HOSTNAME:
326 printf("HTTP Hostname: ");
327 data = record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData);
328 for(i=0; i < len; i++)
329 {
330 if(iscntrl(data[i]))
331 printf("%c",'.');
332 else
333 printf("%c",data[i]);
334 }
335 printf("\n");
336 break;
337
338 case EVENT_INFO_IPV6_SRC:
339 memcpy(&ipAddr, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(struct in6_addr));
340 inet_ntop(AF_INET6, &ipAddr, ip6buf, INET6_ADDRSTRLEN);
341 printf("IPv6 Source Address: %s\n",
342 ip6buf);
343 break;
344
345 case EVENT_INFO_IPV6_DST:
346 memcpy(&ipAddr, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), sizeof(struct in6_addr));
347 inet_ntop(AF_INET6, &ipAddr, ip6buf, INET6_ADDRSTRLEN);
348 printf("IPv6 Destination Address: %s\n",
349 ip6buf);
350 break;
351
352 default :
353 break;
354 }
355
356 }
357
event_dump(u2record * record)358 static void event_dump(u2record *record) {
359 uint8_t *field;
360 int i;
361 Serial_Unified2IDSEvent_legacy event;
362
363 memcpy(&event, record->data, sizeof(Serial_Unified2IDSEvent_legacy));
364
365 /* network to host ordering */
366 /* In the event structure, only the last 40 bits are not 32 bit fields */
367 /* The first 11 fields need to be convertted */
368 field = (uint8_t*)&event;
369 for(i=0; i<11; i++, field+=4) {
370 *(uint32_t*)field = ntohl(*(uint32_t*)field);
371 }
372
373 /* last 3 fields, with the exception of the last most since it's just one byte */
374 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */
375 field += 2;
376 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */
377 /* done changing the network ordering */
378
379
380 printf("\n(Event)\n"
381 "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n"
382 "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n"
383 "\tpriority: %u\tip source: %u.%u.%u.%u\tip destination: %u.%u.%u.%u\n"
384 "\tsrc port: %u\tdest port: %u\tprotocol: %u\timpact_flag: %u\tblocked: %u\n",
385 event.sensor_id, event.event_id,
386 event.event_second, event.event_microsecond,
387 event.signature_id, event.generator_id,
388 event.signature_revision, event.classification_id,
389 event.priority_id, TO_IP(event.ip_source),
390 TO_IP(event.ip_destination), event.sport_itype,
391 event.dport_icode, event.protocol,
392 event.impact_flag, event.blocked);
393 }
394
event6_dump(u2record * record)395 static void event6_dump(u2record *record) {
396 uint8_t *field;
397 int i;
398 Serial_Unified2IDSEventIPv6_legacy event;
399 char ip6buf[INET6_ADDRSTRLEN+1];
400
401 memcpy(&event, record->data, sizeof(Serial_Unified2IDSEventIPv6_legacy));
402
403 /* network to host ordering */
404 /* In the event structure, only the last 40 bits are not 32 bit fields */
405 /* The first fields need to be convertted */
406 field = (uint8_t*)&event;
407 for(i=0; i<9; i++, field+=4) {
408 *(uint32_t*)field = ntohl(*(uint32_t*)field);
409 }
410
411 field = field + 2*sizeof(struct in6_addr);
412
413 /* last 3 fields, with the exception of the last most since it's just one byte */
414 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */
415 field += 2;
416 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */
417 /* done changing the network ordering */
418
419 inet_ntop(AF_INET6, &event.ip_source, ip6buf, INET6_ADDRSTRLEN);
420
421 printf("\n(IPv6 Event)\n"
422 "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n"
423 "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n"
424 "\tpriority: %u\tip source: %s\t",
425 event.sensor_id, event.event_id,
426 event.event_second, event.event_microsecond,
427 event.signature_id, event.generator_id,
428 event.signature_revision, event.classification_id,
429 event.priority_id, ip6buf);
430
431
432 inet_ntop(AF_INET6, &event.ip_destination, ip6buf, INET6_ADDRSTRLEN);
433 printf("ip destination: %s\n"
434 "\tsrc port: %u\tdest port: %u\tprotocol: %u\timpact_flag: %u\tblocked: %u\n",
435 ip6buf, event.sport_itype,
436 event.dport_icode, event.protocol,
437 event.impact_flag, event.blocked);
438 }
439
440
441
event2_dump(u2record * record)442 static void event2_dump(u2record *record) {
443 uint8_t *field;
444 int i;
445
446 Serial_Unified2IDSEvent event;
447
448 memcpy(&event, record->data, sizeof(Serial_Unified2IDSEvent));
449
450 /* network to host ordering */
451 /* In the event structure, only the last 40 bits are not 32 bit fields */
452 /* The first 11 fields need to be convertted */
453 field = (uint8_t*)&event;
454 for(i=0; i<11; i++, field+=4) {
455 *(uint32_t*)field = ntohl(*(uint32_t*)field);
456 }
457
458 /* last 3 fields, with the exception of the last most since it's just one byte */
459 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */
460 field += 2;
461 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */
462 field +=6;
463 *(uint32_t*)field = ntohl(*(uint32_t*)field); /* mpls_label */
464 field += 4;
465 /* policy_id and vlanid */
466 for(i=0; i<2; i++, field+=2) {
467 *(uint16_t*)field = ntohs(*(uint16_t*)field);
468 }
469 /* done changing the network ordering */
470
471
472 printf("\n(Event)\n"
473 "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n"
474 "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n"
475 "\tpriority: %u\tip source: %u.%u.%u.%u\tip destination: %u.%u.%u.%u\n"
476 "\tsrc port: %u\tdest port: %u\tprotocol: %u\timpact_flag: %u\tblocked: %u\n"
477 "\tmpls label: %u\tvland id: %u\tpolicy id: %u\n",
478 event.sensor_id, event.event_id,
479 event.event_second, event.event_microsecond,
480 event.signature_id, event.generator_id,
481 event.signature_revision, event.classification_id,
482 event.priority_id, TO_IP(event.ip_source),
483 TO_IP(event.ip_destination), event.sport_itype,
484 event.dport_icode, event.protocol,
485 event.impact_flag, event.blocked,
486 event.mpls_label, event.vlanId, event.pad2);
487
488 }
489
490 #if defined(FEAT_OPEN_APPID)
event3_dump(u2record * record)491 static void event3_dump(u2record *record)
492 {
493 uint8_t *field;
494 int i;
495
496 Serial_Unified2IDSEvent event;
497
498 memcpy(&event, record->data, sizeof(Serial_Unified2IDSEvent));
499
500 /* network to host ordering */
501 /* In the event structure, only the last 40 bits are not 32 bit fields */
502 /* The first 11 fields need to be convertted */
503 field = (uint8_t*)&event;
504 for(i=0; i<11; i++, field+=4) {
505 *(uint32_t*)field = ntohl(*(uint32_t*)field);
506 }
507
508 /* last 3 fields, with the exception of the last most since it's just one byte */
509 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */
510 field += 2;
511 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */
512 field +=6;
513 *(uint32_t*)field = ntohl(*(uint32_t*)field); /* mpls_label */
514 field += 4;
515 /* policy_id and vlanid */
516 for(i=0; i<2; i++, field+=2) {
517 *(uint16_t*)field = ntohs(*(uint16_t*)field);
518 }
519 /* done changing the network ordering */
520
521
522 printf("\n(Event)\n"
523 "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n"
524 "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n"
525 "\tpriority: %u\tip source: %u.%u.%u.%u\tip destination: %u.%u.%u.%u\n"
526 "\tsrc port: %u\tdest port: %u\tprotocol: %u\timpact_flag: %u\tblocked: %u\n"
527 "\tmpls label: %u\tvland id: %u\tpolicy id: %u\tappid: %s\n",
528 event.sensor_id, event.event_id,
529 event.event_second, event.event_microsecond,
530 event.signature_id, event.generator_id,
531 event.signature_revision, event.classification_id,
532 event.priority_id, TO_IP(event.ip_source),
533 TO_IP(event.ip_destination), event.sport_itype,
534 event.dport_icode, event.protocol,
535 event.impact_flag, event.blocked,
536 event.mpls_label, event.vlanId, event.pad2, event.app_name);
537
538 }
539
540 #endif /* defined(FEAT_OPEN_APPID) */
event2_6_dump(u2record * record)541 static void event2_6_dump(u2record *record) {
542 uint8_t *field;
543 int i;
544 char ip6buf[INET6_ADDRSTRLEN+1];
545 Serial_Unified2IDSEventIPv6 event;
546
547 memcpy(&event, record->data, sizeof(Serial_Unified2IDSEventIPv6));
548
549 /* network to host ordering */
550 /* In the event structure, only the last 40 bits are not 32 bit fields */
551 /* The first fields need to be convertted */
552 field = (uint8_t*)&event;
553 for(i=0; i<9; i++, field+=4) {
554 *(uint32_t*)field = ntohl(*(uint32_t*)field);
555 }
556
557 field = field + 2*sizeof(struct in6_addr);
558
559 /* last 3 fields, with the exception of the last most since it's just one byte */
560 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */
561 field += 2;
562 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */
563 field +=6;
564 *(uint32_t*)field = ntohl(*(uint32_t*)field); /* mpls_label */
565 field += 4;
566 /* policy_id and vlanid */
567 for(i=0; i<2; i++, field+=2) {
568 *(uint16_t*)field = ntohs(*(uint16_t*)field);
569 }
570 /* done changing the network ordering */
571
572 inet_ntop(AF_INET6, &event.ip_source, ip6buf, INET6_ADDRSTRLEN);
573
574 printf("\n(IPv6 Event)\n"
575 "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n"
576 "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n"
577 "\tpriority: %u\tip source: %s\t",
578 event.sensor_id, event.event_id,
579 event.event_second, event.event_microsecond,
580 event.signature_id, event.generator_id,
581 event.signature_revision, event.classification_id,
582 event.priority_id, ip6buf);
583
584
585 inet_ntop(AF_INET6, &event.ip_destination, ip6buf, INET6_ADDRSTRLEN);
586 printf("ip destination: %s\n"
587 "\tsrc port: %u\tdest port: %u\tprotocol: %u\timpact_flag: %u\tblocked: %u\n"
588 "\tmpls label: %u\tvland id: %u\tpolicy id: %u\n",
589 ip6buf, event.sport_itype,
590 event.dport_icode, event.protocol,
591 event.impact_flag, event.blocked,
592 event.mpls_label, event.vlanId,event.pad2);
593
594 }
595
596 #if defined(FEAT_OPEN_APPID)
event3_6_dump(u2record * record)597 static void event3_6_dump(u2record *record) {
598 uint8_t *field;
599 int i;
600 char ip6buf[INET6_ADDRSTRLEN+1];
601 Serial_Unified2IDSEventIPv6 event;
602
603 memcpy(&event, record->data, sizeof(Serial_Unified2IDSEventIPv6));
604
605 /* network to host ordering */
606 /* In the event structure, only the last 40 bits are not 32 bit fields */
607 /* The first fields need to be convertted */
608 field = (uint8_t*)&event;
609 for(i=0; i<9; i++, field+=4) {
610 *(uint32_t*)field = ntohl(*(uint32_t*)field);
611 }
612
613 field = field + 2*sizeof(struct in6_addr);
614
615 /* last 3 fields, with the exception of the last most since it's just one byte */
616 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* sport_itype */
617 field += 2;
618 *(uint16_t*)field = ntohs(*(uint16_t*)field); /* dport_icode */
619 field +=6;
620 *(uint32_t*)field = ntohl(*(uint32_t*)field); /* mpls_label */
621 field += 4;
622 /* policy_id and vlanid */
623 for(i=0; i<2; i++, field+=2) {
624 *(uint16_t*)field = ntohs(*(uint16_t*)field);
625 }
626 /* done changing the network ordering */
627
628 inet_ntop(AF_INET6, &event.ip_source, ip6buf, INET6_ADDRSTRLEN);
629
630 printf("\n(IPv6 Event)\n"
631 "\tsensor id: %u\tevent id: %u\tevent second: %u\tevent microsecond: %u\n"
632 "\tsig id: %u\tgen id: %u\trevision: %u\t classification: %u\n"
633 "\tpriority: %u\tip source: %s\t",
634 event.sensor_id, event.event_id,
635 event.event_second, event.event_microsecond,
636 event.signature_id, event.generator_id,
637 event.signature_revision, event.classification_id,
638 event.priority_id, ip6buf);
639
640
641 inet_ntop(AF_INET6, &event.ip_destination, ip6buf, INET6_ADDRSTRLEN);
642 printf("ip destination: %s\n"
643 "\tsrc port: %u\tdest port: %u\tprotocol: %u\timpact_flag: %u\tblocked: %u\n"
644 "\tmpls label: %u\tvland id: %u\tpolicy id: %u\tappid: %s\n",
645 ip6buf, event.sport_itype,
646 event.dport_icode, event.protocol,
647 event.impact_flag, event.blocked,
648 event.mpls_label, event.vlanId,event.pad2, event.app_name);
649
650 }
651
appid_dump(u2record * record)652 static void appid_dump(u2record *record) {
653 uint8_t *field = (uint8_t*)record->data;
654 unsigned i;
655 unsigned appCnt;
656 unsigned statTime;
657
658 /* network to host ordering */
659 /* In the event structure, only the last 40 bits are not 32 bit fields */
660 /* The first fields need to be convertted */
661 statTime = ntohl(*(uint32_t*)field);
662 field += 4;
663 appCnt = ntohl(*(uint32_t*)field);
664 field += 4;
665
666 printf("\n(AppId Stats)\n"
667 " event second: %u\tRecordCount: %u\n",
668 statTime, appCnt);
669 for(i=0; i<appCnt; i++)
670 {
671 char appName[MAX_EVENT_APPNAME_LEN];
672 memcpy(appName, field, sizeof(appName));
673 field += MAX_EVENT_APPNAME_LEN;
674
675 int txBytes = ntohl(*(uint32_t*)field);
676 field += 4;
677 int rxBytes = ntohl(*(uint32_t*)field);
678 field += 4;
679
680 printf(" -----------\n\tApp:%s\n\tbytes_out: %u\n\tbytes_in: %u\n",
681 appName, txBytes, rxBytes);
682 }
683 }
684
685 #endif /* defined(FEAT_OPEN_APPID) */
686
687 #define LOG_CHARS 16
688
LogBuffer(const uint8_t * p,unsigned n)689 static void LogBuffer (const uint8_t* p, unsigned n)
690 {
691 char hex[(3*LOG_CHARS)+1];
692 char txt[LOG_CHARS+1];
693 unsigned odx = 0, idx = 0, at = 0;
694
695 for ( idx = 0; idx < n; idx++)
696 {
697 uint8_t byte = p[idx];
698 sprintf(hex + 3*odx, "%2.02X ", byte);
699 txt[odx++] = isprint(byte) ? byte : '.';
700
701 if ( odx == LOG_CHARS )
702 {
703 txt[odx] = hex[3*odx] = '\0';
704 printf("[%5u] %s %s\n", at, hex, txt);
705 at = idx + 1;
706 odx = 0;
707 }
708 }
709 if ( odx )
710 {
711 txt[odx] = hex[3*odx] = '\0';
712 printf("[%5u] %-48.48s %s\n", at, hex, txt);
713 }
714 }
715
packet_dump(u2record * record)716 static void packet_dump(u2record *record) {
717 uint32_t counter;
718 uint8_t *field;
719
720 unsigned offset = sizeof(Serial_Unified2Packet)-4;
721 unsigned reclen = record->length - offset;
722
723 Serial_Unified2Packet packet;
724 memcpy(&packet, record->data, sizeof(Serial_Unified2Packet));
725
726 /* network to host ordering */
727 /* The first 7 fields need to be convertted */
728 field = (uint8_t*)&packet;
729 for(counter=0; counter<7; counter++, field+=4) {
730 *(uint32_t*)field = ntohl(*(uint32_t*)field);
731 }
732 /* done changing from network ordering */
733
734 printf("\nPacket\n"
735 "\tsensor id: %u\tevent id: %u\tevent second: %u\n"
736 "\tpacket second: %u\tpacket microsecond: %u\n"
737 "\tlinktype: %u\tpacket_length: %u\n",
738 packet.sensor_id, packet.event_id, packet.event_second,
739 packet.packet_second, packet.packet_microsecond, packet.linktype,
740 packet.packet_length);
741
742
743 if ( record->length <= offset )
744 return;
745
746 if ( packet.packet_length != reclen )
747 {
748 printf("ERROR: logged %u but packet_length = %u\n",
749 record->length-offset, packet.packet_length);
750
751 if ( packet.packet_length < reclen )
752 {
753 reclen = packet.packet_length;
754 s_off = reclen + offset;
755 }
756 }
757 LogBuffer(record->data+offset, reclen);
758 }
759
u2dump(char * file)760 static int u2dump(char *file) {
761 u2record record;
762 u2iterator *it = new_iterator(file);
763
764 memset(&record, 0, sizeof(record));
765
766 if(!it) {
767 printf("u2dump: Failed to create new iterator with file: %s\n", file);
768 return -1;
769 }
770
771 while( get_record(it, &record) == SUCCESS ) {
772 if(record.type == UNIFIED2_IDS_EVENT) event_dump(&record);
773 else if(record.type == UNIFIED2_IDS_EVENT_VLAN) event2_dump(&record);
774 else if(record.type == UNIFIED2_PACKET) packet_dump(&record);
775 else if(record.type == UNIFIED2_IDS_EVENT_IPV6) event6_dump(&record);
776 else if(record.type == UNIFIED2_IDS_EVENT_IPV6_VLAN) event2_6_dump(&record);
777 else if(record.type == UNIFIED2_EXTRA_DATA) extradata_dump(&record);
778 #if defined(FEAT_OPEN_APPID)
779
780 else if(record.type == UNIFIED2_IDS_EVENT_APPID) event3_dump(&record);
781 else if(record.type == UNIFIED2_IDS_EVENT_APPID_IPV6) event3_6_dump(&record);
782 else if(record.type == UNIFIED2_IDS_EVENT_APPSTAT) appid_dump(&record);
783 #endif /* defined(FEAT_OPEN_APPID) */
784 }
785
786 free_iterator(it);
787 if(record.data)
788 free(record.data);
789
790 return 0;
791 }
792
main(int argc,char ** argv)793 int main(int argc, char **argv) {
794 if(argc != 2) {
795 printf("usage: %s <file>\n",argv[0]);
796 return 1;
797 }
798
799 return u2dump(argv[1]);
800 }
801