00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifdef HAVE_CONFIG_H
00041 #include "config.h"
00042 #endif
00043
00044 #include <sys/types.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #ifdef HAVE_STRINGS_H
00048 #include <strings.h>
00049 #endif
00050 #include <errno.h>
00051 #include <time.h>
00052
00053 #include "decode.h"
00054 #include "rules.h"
00055 #include "util.h"
00056 #include "plugbase.h"
00057 #include "spo_plugbase.h"
00058 #include "parser.h"
00059 #include "debug.h"
00060 #include "mstring.h"
00061 #include "stream.h"
00062 #include "event.h"
00063 #include "generators.h"
00064 #include "snort_packet_header.h"
00065
00066 #include "snort.h"
00067
00068 #ifdef GIDS
00069 #include "inline.h"
00070 #endif
00071
00072 #define SNORT_MAGIC 0xa1b2c3d4
00073 #define ALERT_MAGIC 0xDEAD4137
00074 #define LOG_MAGIC 0xDEAD1080
00075 #define SNORT_VERSION_MAJOR 1
00076 #define SNORT_VERSION_MINOR 2
00077
00078
00079 extern u_int16_t event_id;
00080
00081
00082
00083
00084
00085
00086
00087 typedef struct _UnifiedLogFileHeader
00088 {
00089 u_int32_t magic;
00090 u_int16_t version_major;
00091 u_int16_t version_minor;
00092 u_int32_t timezone;
00093 u_int32_t sigfigs;
00094 u_int32_t snaplen;
00095 u_int32_t linktype;
00096 } UnifiedLogFileHeader;
00097
00098 typedef struct _UnifiedAlertFileHeader
00099 {
00100 u_int32_t magic;
00101 u_int32_t version_major;
00102 u_int32_t version_minor;
00103 u_int32_t timezone;
00104 } UnifiedAlertFileHeader;
00105
00106
00107
00108
00109
00110
00111
00112 typedef struct _UnifiedLog
00113 {
00114 Event event;
00115 u_int32_t flags;
00116 SnortPktHeader pkth;
00117 } UnifiedLog;
00118
00119
00120
00121
00122
00123
00124 typedef struct _UnifiedAlert
00125 {
00126 Event event;
00127 struct timeval ts;
00128 u_int32_t sip;
00129 u_int32_t dip;
00130 u_int16_t sp;
00131 u_int16_t dp;
00132 u_int32_t protocol;
00133 u_int32_t flags;
00134 } UnifiedAlert;
00135
00136
00137
00138
00139 extern OptTreeNode *otn_tmp;
00140 extern int thiszone;
00141
00142 #ifdef GIDS
00143 #ifndef IPFW
00144 extern ipq_packet_msg_t *g_m;
00145 #endif
00146 #endif
00147
00148
00149 typedef struct _UnifiedConfig
00150 {
00151 char *filename;
00152 FILE *stream;
00153 unsigned int limit;
00154 unsigned int current;
00155 } UnifiedConfig;
00156
00157 typedef struct _FileHeader
00158 {
00159 u_int32_t magic;
00160 u_int32_t flags;
00161 } FileHeader;
00162
00163 typedef struct _DataHeader
00164 {
00165 u_int32_t type;
00166 u_int32_t length;
00167 } DataHeader;
00168
00169 #define UNIFIED_MAGIC 0x2dac5ceb
00170
00171 #define UNIFIED_TYPE_ALERT 0x1
00172 #define UNIFIED_TYPE_PACKET_ALERT 0x2
00173
00174
00175 #ifdef GIDS
00176 EtherHdr g_ethernet;
00177 #endif
00178
00179
00180 static UnifiedConfig *UnifiedParseArgs(char *, char *);
00181 static void UnifiedCleanExit(int, void *);
00182 static void UnifiedRestart(int, void *);
00183
00184
00185 static void UnifiedInit(u_char *);
00186 static void UnifiedInitFile(UnifiedConfig *);
00187 static void UnifiedRotateFile(UnifiedConfig *);
00188 static void UnifiedLogAlert(Packet *, char *, void *, Event *);
00189 static void UnifiedLogPacketAlert(Packet *, char *, void *, Event *);
00190 static void RealUnifiedLogAlert(Packet *, char *, void *, Event *,
00191 DataHeader *);
00192 static void RealUnifiedLogPacketAlert(Packet *, char *, void *, Event *,
00193 DataHeader *);
00194 void RealUnifiedLogStreamAlert(Packet *,char *,void *,Event *,DataHeader *);
00195 static void UnifiedRotateFile(UnifiedConfig *data);
00196
00197
00198 static void UnifiedAlertInit(u_char *);
00199 static void UnifiedInitAlertFile(UnifiedConfig *);
00200 static void UnifiedAlertRotateFile(UnifiedConfig *data);
00201 static void OldUnifiedLogAlert(Packet *, char *, void *, Event *);
00202
00203
00204
00205 static void UnifiedLogInit(u_char *);
00206 static void UnifiedInitLogFile(UnifiedConfig *);
00207 static void OldUnifiedLogPacketAlert(Packet *, char *, void *, Event *);
00208 static void UnifiedLogRotateFile(UnifiedConfig *data);
00209
00210
00211 static UnifiedConfig *unifiedConfig;
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 void UnifiedSetup()
00226 {
00227
00228
00229 RegisterOutputPlugin("log_unified", NT_OUTPUT_LOG, UnifiedLogInit);
00230 RegisterOutputPlugin("alert_unified", NT_OUTPUT_ALERT, UnifiedAlertInit);
00231 RegisterOutputPlugin("unified", NT_OUTPUT_SPECIAL, UnifiedInit);
00232 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output plugin: Unified logging/alerting "
00233 "is setup...\n"););
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 void UnifiedInit(u_char *args)
00248 {
00249 if(unifiedConfig)
00250 {
00251 FatalError("unified can only be instantiated once\n");
00252 }
00253
00254
00255 pv.log_plugin_active = 1;
00256 pv.alert_plugin_active = 1;
00257
00258
00259 unifiedConfig = UnifiedParseArgs(args, "snort-unified");
00260
00261 UnifiedInitFile(unifiedConfig);
00262
00263
00264
00265
00266 AddFuncToOutputList(UnifiedLogAlert, NT_OUTPUT_ALERT, unifiedConfig);
00267 AddFuncToOutputList(UnifiedLogPacketAlert, NT_OUTPUT_LOG, unifiedConfig);
00268
00269 AddFuncToCleanExitList(UnifiedCleanExit, unifiedConfig);
00270 AddFuncToRestartList(UnifiedRestart, unifiedConfig);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 static void UnifiedInitFile(UnifiedConfig *data)
00283 {
00284 time_t curr_time;
00285 char logdir[STD_BUF];
00286 FileHeader hdr;
00287 int value;
00288
00289 bzero(logdir, STD_BUF);
00290 curr_time = time(NULL);
00291
00292 if(data == NULL)
00293 FatalError("SpoUnified: Unable to get context data\n");
00294
00295 if(*(data->filename) == '/')
00296 value = snprintf(logdir, STD_BUF, "%s.%lu", data->filename,
00297 (unsigned long)curr_time);
00298 else
00299 value = snprintf(logdir, STD_BUF, "%s/%s.%lu", pv.log_dir,
00300 data->filename, (unsigned long)curr_time);
00301
00302 if(value == -1)
00303 FatalError("SpoUnified: filepath too long\n");
00304
00305
00306
00307 if((data->stream = fopen(logdir, "wb")) == NULL)
00308 FatalError("UnifiedInitLogFile(%s): %s\n", logdir, strerror(errno));
00309
00310
00311 hdr.magic = UNIFIED_MAGIC;
00312 hdr.flags = 0;
00313
00314 if(fwrite((char *)&hdr, sizeof(hdr), 1, data->stream) != 1)
00315 {
00316 FatalError("SpoUnified: InitOutputFile(): %s", strerror(errno));
00317 }
00318
00319 fflush(data->stream);
00320
00321 return;
00322 }
00323
00324 void UnifiedRotateFile(UnifiedConfig *data)
00325 {
00326 fclose(data->stream);
00327 data->current = 0;
00328 UnifiedInitFile(data);
00329 }
00330
00331
00332 static char write_pkt_buffer[sizeof(DataHeader)+IP_MAXPACKET];
00333
00334 int UnifiedLogData(u_int32_t type, u_int32_t length, void *data)
00335 {
00336 DataHeader dHdr;
00337 if(!unifiedConfig)
00338 {
00339 FatalError("Unified output not configured\n");
00340 }
00341
00342
00343 if(!data)
00344 {
00345 LogMessage("WARNING: call to LogUnified with NULL data\n");
00346 return -1;
00347 }
00348
00349
00350 if(length <= 0)
00351 {
00352 LogMessage("Empty Alert ....LogUnified bailing \n");
00353 return -1;
00354 }
00355 memset(write_pkt_buffer,'\0',sizeof(DataHeader)+IP_MAXPACKET);
00356
00357 dHdr.type = type;
00358 dHdr.length = length;
00359
00360 memcpy(write_pkt_buffer,&dHdr,sizeof(DataHeader));
00361 memcpy(write_pkt_buffer+sizeof(DataHeader),(char *)data,length);
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 if(fwrite(write_pkt_buffer,length+sizeof(DataHeader),1,unifiedConfig->stream) != 1)
00374 {
00375 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
00376 }
00377 fflush(unifiedConfig->stream);
00378
00379 return 0;
00380 }
00381
00382 void UnifiedLogAlert(Packet *p, char *msg, void *arg, Event *event)
00383 {
00384 DataHeader dHdr;
00385 dHdr.type = UNIFIED_TYPE_ALERT;
00386 dHdr.length = sizeof(UnifiedAlert);
00387
00388
00389 RealUnifiedLogAlert(p, msg, arg, event, &dHdr);
00390 }
00391
00392 void RealUnifiedLogAlert(Packet *p, char *msg, void *arg, Event *event,
00393 DataHeader *dHdr)
00394 {
00395 UnifiedConfig *data = (UnifiedConfig *)arg;
00396 UnifiedAlert alertdata;
00397 Stream * s;
00398 StreamPacketData * spd;
00399
00400 bzero(&alertdata, sizeof(alertdata));
00401
00402 if(event != NULL)
00403 {
00404 alertdata.event.sig_generator = event->sig_generator;
00405 alertdata.event.sig_id = event->sig_id;
00406 alertdata.event.sig_rev = event->sig_rev;
00407 alertdata.event.classification = event->classification;
00408 alertdata.event.priority = event->priority;
00409 alertdata.event.event_id = event->event_id;
00410 alertdata.event.event_reference = event->event_reference;
00411 alertdata.event.ref_time.tv_sec = event->ref_time.tv_sec;
00412 alertdata.event.ref_time.tv_usec = event->ref_time.tv_usec;
00413
00414 }
00415
00416 if(p)
00417 {
00418 alertdata.ts.tv_sec = p->pkth->ts.tv_sec;
00419 alertdata.ts.tv_usec = p->pkth->ts.tv_usec;
00420
00421 if(p->packet_flags & PKT_REBUILT_STREAM)
00422 {
00423 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "man:Logging rebuilt stream data.\n"););
00424
00425 s = (Stream *) p->streamptr;
00426
00427
00428 spd = (StreamPacketData *) ubi_btFirst((ubi_btNodePtr)&s->data);
00429
00430
00431 if(spd != NULL )
00432 {
00433 alertdata.ts.tv_sec = spd->pkth.ts.tv_sec;
00434 alertdata.ts.tv_usec = spd->pkth.ts.tv_usec;
00435 }
00436 }
00437
00438 if(p->iph != NULL)
00439 {
00440
00441 alertdata.sip = ntohl(p->iph->ip_src.s_addr);
00442 alertdata.dip = ntohl(p->iph->ip_dst.s_addr);
00443 if(p->iph->ip_proto == IPPROTO_ICMP)
00444 {
00445 if(p->icmph != NULL)
00446 {
00447 alertdata.sp = p->icmph->type;
00448 alertdata.dp = p->icmph->code;
00449 }
00450 }
00451 else
00452 {
00453 alertdata.sp = p->sp;
00454 alertdata.dp = p->dp;
00455 }
00456 alertdata.protocol = p->iph->ip_proto;
00457 alertdata.flags = p->packet_flags;
00458 }
00459 }
00460
00461
00462 if(dHdr == NULL)
00463 {
00464 if((data->current + sizeof(UnifiedAlert)) > data->limit)
00465 UnifiedAlertRotateFile(data);
00466 }
00467 else
00468 {
00469 if((data->current + sizeof(UnifiedAlert)) > data->limit)
00470 UnifiedRotateFile(data);
00471 }
00472
00473 if(dHdr)
00474 {
00475 if(fwrite((char *)dHdr, sizeof(DataHeader), 1, data->stream) != 1)
00476 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
00477 data->current += sizeof(DataHeader);
00478 }
00479
00480 if(fwrite((char *)&alertdata, sizeof(UnifiedAlert), 1, data->stream) != 1)
00481 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
00482
00483
00484 fflush(data->stream);
00485 data->current += sizeof(UnifiedAlert);
00486 }
00487
00488
00489 void UnifiedLogPacketAlert(Packet *p, char *msg, void *arg, Event *event)
00490 {
00491 DataHeader dHdr;
00492 dHdr.type = UNIFIED_TYPE_PACKET_ALERT;
00493 dHdr.length = sizeof(UnifiedLog);
00494
00495 if(p->packet_flags & PKT_REBUILT_STREAM)
00496 {
00497 DEBUG_WRAP(DebugMessage(DEBUG_LOG,
00498 "[*] Reassembled packet, dumping stream packets\n"););
00499 RealUnifiedLogStreamAlert(p, msg, arg, event, &dHdr);
00500 }
00501 else
00502 {
00503 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "[*] Logging unified packets...\n"););
00504 RealUnifiedLogPacketAlert(p, msg, arg, event, &dHdr);
00505 }
00506
00507 }
00508
00509
00510 void RealUnifiedLogPacketAlert(Packet *p, char *msg, void *arg, Event *event,
00511 DataHeader *dHdr)
00512 {
00513 UnifiedLog logheader;
00514 UnifiedConfig *data = (UnifiedConfig *)arg;
00515
00516 if(event != NULL)
00517 {
00518 logheader.event.sig_generator = event->sig_generator;
00519 logheader.event.sig_id = event->sig_id;
00520 logheader.event.sig_rev = event->sig_rev;
00521 logheader.event.classification = event->classification;
00522 logheader.event.priority = event->priority;
00523 logheader.event.event_id = event->event_id;
00524 logheader.event.event_reference = event->event_reference;
00525 logheader.event.ref_time.tv_sec = event->ref_time.tv_sec;
00526 logheader.event.ref_time.tv_usec = event->ref_time.tv_usec;
00527
00528 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "------------\n");
00529 DebugMessage(DEBUG_LOG, "gen: %u\n", logheader.event.sig_generator);
00530 DebugMessage(DEBUG_LOG, "sid: %u\n", logheader.event.sig_id);
00531 DebugMessage(DEBUG_LOG, "rev: %u\n", logheader.event.sig_rev);
00532 DebugMessage(DEBUG_LOG, "cls: %u\n", logheader.event.classification);
00533 DebugMessage(DEBUG_LOG, "pri: %u\n", logheader.event.priority);
00534 DebugMessage(DEBUG_LOG, "eid: %u\n", logheader.event.event_id);
00535 DebugMessage(DEBUG_LOG, "erf: %u\n", logheader.event.event_reference);
00536 DebugMessage(DEBUG_LOG, "sec: %lu\n", logheader.event.ref_time.tv_sec);
00537 DebugMessage(DEBUG_LOG, "usc: %lu\n", logheader.event.ref_time.tv_usec););
00538 }
00539
00540 if(p)
00541 {
00542 logheader.flags = p->packet_flags;
00543
00544
00545
00546
00547
00548 memcpy(&logheader.pkth, p->pkth, sizeof(SnortPktHeader));
00549 }
00550 else
00551 {
00552 logheader.flags = 0;
00553 logheader.pkth.ts.tv_sec = 0;
00554 logheader.pkth.ts.tv_usec = 0;
00555 logheader.pkth.caplen = 0;
00556 logheader.pkth.pktlen = 0;
00557 }
00558
00559
00560 if(dHdr == NULL)
00561 {
00562 if((data->current + sizeof(UnifiedLog) + logheader.pkth.caplen) >
00563 data->limit)
00564 UnifiedLogRotateFile(data);
00565 }
00566 else
00567 {
00568 if((data->current + sizeof(UnifiedLog) + sizeof(DataHeader)
00569 + logheader.pkth.caplen) > data->limit)
00570 UnifiedRotateFile(data);
00571 }
00572 if(dHdr)
00573 {
00574 if(fwrite((char *)dHdr, sizeof(DataHeader), 1, data->stream) != 1)
00575 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
00576 data->current += sizeof(DataHeader);
00577 }
00578
00579
00580 if(fwrite((char*)&logheader, sizeof(UnifiedLog), 1, data->stream) != 1)
00581 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
00582 data->current += sizeof(UnifiedLog);
00583
00584 if(p)
00585 {
00586 if(fwrite((char*)p->pkt, p->pkth->caplen, 1, data->stream) != 1)
00587 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
00588 data->current += p->pkth->caplen;
00589 }
00590
00591 fflush(data->stream);
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 void RealUnifiedLogStreamAlert(Packet *p, char *msg, void *arg, Event *event,
00601 DataHeader *dHdr)
00602 {
00603 Stream *s = NULL;
00604 StreamPacketData *spd;
00605 UnifiedLog logheader;
00606 UnifiedConfig *data = (UnifiedConfig *)arg;
00607 int once = 0;
00608
00609
00610 if(event != NULL)
00611 {
00612 logheader.event.sig_generator = event->sig_generator;
00613 logheader.event.sig_id = event->sig_id;
00614 logheader.event.sig_rev = event->sig_rev;
00615 logheader.event.classification = event->classification;
00616 logheader.event.priority = event->priority;
00617 logheader.event.event_id = event->event_id;
00618 logheader.event.event_reference = event->event_reference;
00619
00620
00621 logheader.event.ref_time.tv_sec = event->ref_time.tv_sec;
00622 logheader.event.ref_time.tv_usec = event->ref_time.tv_usec;
00623
00624 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "------------\n");
00625 DebugMessage(DEBUG_LOG, "gen: %u\n", logheader.event.sig_generator);
00626 DebugMessage(DEBUG_LOG, "sid: %u\n", logheader.event.sig_id);
00627 DebugMessage(DEBUG_LOG, "rev: %u\n", logheader.event.sig_rev);
00628 DebugMessage(DEBUG_LOG, "cls: %u\n", logheader.event.classification);
00629 DebugMessage(DEBUG_LOG, "pri: %u\n", logheader.event.priority);
00630 DebugMessage(DEBUG_LOG, "eid: %u\n", logheader.event.event_id);
00631 DebugMessage(DEBUG_LOG, "erf: %u\n",
00632 logheader.event.event_reference);
00633 DebugMessage(DEBUG_LOG, "sec: %lu\n",
00634 logheader.event.ref_time.tv_sec);
00635 DebugMessage(DEBUG_LOG, "usc: %lu\n",
00636 logheader.event.ref_time.tv_usec););
00637 }
00638
00639
00640 if(p)
00641 {
00642 s = (Stream *) p->streamptr;
00643
00644
00645 spd = (StreamPacketData *) ubi_btFirst((ubi_btNodePtr)&s->data);
00646
00647
00648 do
00649 {
00650
00651
00652
00653 if(spd->chuck != SEG_UNASSEMBLED)
00654 {
00655
00656 memcpy(&logheader.pkth, &spd->pkth, sizeof(SnortPktHeader));
00657
00658
00659 if(dHdr == NULL)
00660 {
00661 if((data->current +
00662 sizeof(UnifiedLog)+
00663 logheader.pkth.caplen) >
00664 data->limit)
00665 {
00666 UnifiedLogRotateFile(data);
00667 }
00668 }
00669 else
00670 {
00671 if((data->current + sizeof(UnifiedLog) + sizeof(DataHeader)
00672 + logheader.pkth.caplen) > data->limit)
00673 UnifiedRotateFile(data);
00674 }
00675
00676 if(dHdr)
00677 {
00678 if(fwrite((char*)dHdr,sizeof(DataHeader),1,data->stream)
00679 != 1)
00680 FatalError("SpoUnified: write failed: %s\n",
00681 strerror(errno));
00682 data->current += sizeof(DataHeader);
00683 }
00684
00685 if(fwrite((char*)&logheader,sizeof(UnifiedLog),1,data->stream)
00686 != 1)
00687 FatalError("SpoUnified: write failed: %s\n",
00688 strerror(errno));
00689
00690 data->current += sizeof(UnifiedLog);
00691
00692 if(spd->pkt)
00693 {
00694 if(fwrite((char*)spd->pkt,logheader.pkth.caplen,1
00695 ,data->stream) != 1)
00696 FatalError("SpoUnified: write failed: %s\n",
00697 strerror(errno));
00698
00699 data->current += logheader.pkth.caplen;
00700 }
00701
00702
00703 if(!once++)
00704 {
00705 logheader.event.sig_generator = GENERATOR_TAG;
00706 logheader.event.sig_id = TAG_LOG_PKT;
00707 logheader.event.sig_rev = 1;
00708 logheader.event.classification = 0;
00709 logheader.event.priority = event->priority;
00710
00711
00712 }
00713 }
00714
00715 } while((spd=(StreamPacketData*)ubi_btNext((ubi_btNodePtr)spd))
00716 !=NULL);
00717 }
00718
00719 fflush(data->stream);
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 UnifiedConfig *UnifiedParseArgs(char *args, char *default_filename)
00736 {
00737 UnifiedConfig *tmp;
00738 int limit = 0;
00739
00740 tmp = (UnifiedConfig *)calloc(sizeof(UnifiedConfig), sizeof(char));
00741
00742 if(tmp == NULL)
00743 {
00744 FatalError("Unable to allocate Unified Data struct!\n");
00745 }
00746
00747 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Args: %s\n", args););
00748
00749 if(args != NULL)
00750 {
00751 char **toks;
00752 int num_toks;
00753 int i = 0;
00754 toks = mSplit(args, ",", 31, &num_toks, '\\');
00755 for(i = 0; i < num_toks; ++i)
00756 {
00757 char **stoks;
00758 int num_stoks;
00759 char *index = toks[i];
00760 while(isspace((int)*index))
00761 ++index;
00762
00763 stoks = mSplit(index, " ", 2, &num_stoks, 0);
00764
00765 if(strcasecmp("filename", stoks[0]) == 0)
00766 {
00767 if(num_stoks > 1 && tmp->filename == NULL)
00768 tmp->filename = strdup(stoks[1]);
00769 else
00770 LogMessage("Argument Error in %s(%i): %s\n",
00771 file_name, file_line, index);
00772 }
00773 if(strcasecmp("limit", stoks[0]) == 0)
00774 {
00775 if(num_stoks > 1 && limit == 0)
00776 {
00777 limit = atoi(stoks[1]);
00778 }
00779 else
00780 {
00781 LogMessage("Argument Error in %s(%i): %s\n",
00782 file_name, file_line, index);
00783 }
00784 }
00785 do
00786 free(stoks[--num_stoks]);
00787 while(num_stoks);
00788 }
00789 do
00790 free(toks[--num_toks]);
00791 while(num_toks);
00792 }
00793
00794 if(tmp->filename == NULL)
00795 tmp->filename = strdup(default_filename);
00796
00797
00798
00799 if(limit <= 0)
00800 {
00801 limit = 128;
00802 }
00803 if(limit > 512)
00804 {
00805 LogMessage("spo_unified %s(%d)=> Lowering limit of %iMB to 512MB\n", file_name, file_line, limit);
00806 limit = 512;
00807 }
00808
00809
00810 tmp->limit = limit << 20;
00811
00812 return tmp;
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 static void UnifiedCleanExit(int signal, void *arg)
00827 {
00828
00829 UnifiedConfig *data = (UnifiedConfig *)arg;
00830
00831 DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "SpoUnified: CleanExit\n"););
00832
00833 fclose(data->stream);
00834
00835
00836 free(data->filename);
00837 free(data);
00838 }
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 static void UnifiedRestart(int signal, void *arg)
00853 {
00854 UnifiedConfig *data = (UnifiedConfig *)arg;
00855
00856 DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "SpoUnified: Restart\n"););
00857
00858 fclose(data->stream);
00859 free(data->filename);
00860 free(data);
00861 }
00862
00863
00864
00865
00866 void UnifiedAlertInit(u_char *args)
00867 {
00868 UnifiedConfig *data;
00869
00870 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Unified Alert Initialized\n"););
00871
00872 pv.alert_plugin_active = 1;
00873
00874
00875 data = UnifiedParseArgs(args, "snort-unified.alert");
00876
00877 UnifiedInitAlertFile(data);
00878
00879
00880
00881
00882 AddFuncToOutputList(OldUnifiedLogAlert, NT_OUTPUT_ALERT, data);
00883 AddFuncToCleanExitList(UnifiedCleanExit, data);
00884 AddFuncToRestartList(UnifiedRestart, data);
00885 }
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 void UnifiedInitAlertFile(UnifiedConfig *data)
00896 {
00897 time_t curr_time;
00898 char logdir[STD_BUF];
00899 int value;
00900 UnifiedAlertFileHeader hdr;
00901
00902 bzero(logdir, STD_BUF);
00903 curr_time = time(NULL);
00904
00905 if(data->filename[0] == '/')
00906 value = snprintf(logdir, STD_BUF, "%s.%lu", data->filename,
00907 (unsigned long)curr_time);
00908 else
00909 value = snprintf(logdir, STD_BUF, "%s/%s.%lu", pv.log_dir,
00910 data->filename, (unsigned long)curr_time);
00911
00912 if(value == -1)
00913 {
00914 FatalError("unified log file logging path and file name are "
00915 "too long, aborting!\n");
00916 }
00917
00918 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "Opening %s\n", logdir););
00919
00920 if((data->stream = fopen(logdir, "wb+")) == NULL)
00921 {
00922 FatalError("UnifiedInitAlertFile(%s): %s\n", logdir, strerror(errno));
00923 }
00924
00925 hdr.magic = ALERT_MAGIC;
00926 hdr.version_major = 1;
00927 hdr.version_minor = 81;
00928 hdr.timezone = thiszone;
00929
00930 if(fwrite((char *)&hdr, sizeof(hdr), 1, data->stream) != 1)
00931 {
00932 FatalError("UnifiedAlertInit(): %s\n", strerror(errno));
00933 }
00934
00935 fflush(data->stream);
00936
00937 return;
00938 }
00939
00940
00941 void OldUnifiedLogAlert(Packet *p, char *msg, void *arg, Event *event)
00942 {
00943 RealUnifiedLogAlert(p, msg, arg, event, NULL);
00944 }
00945
00946 void UnifiedAlertRotateFile(UnifiedConfig *data)
00947 {
00948
00949 fclose(data->stream);
00950 data->current = 0;
00951 UnifiedInitAlertFile(data);
00952 }
00953
00954
00955
00956 void UnifiedLogInit(u_char *args)
00957 {
00958 UnifiedConfig *UnifiedInfo;
00959
00960 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Unified Log Initialized\n"););
00961
00962
00963 pv.log_plugin_active = 1;
00964
00965
00966 UnifiedInfo = UnifiedParseArgs(args, "snort-unified.log");
00967
00968
00969
00970 UnifiedInitLogFile(UnifiedInfo);
00971
00972 pv.log_bitmap |= LOG_UNIFIED;
00973
00974
00975 AddFuncToOutputList(OldUnifiedLogPacketAlert, NT_OUTPUT_LOG, UnifiedInfo);
00976 AddFuncToCleanExitList(UnifiedCleanExit, UnifiedInfo);
00977 AddFuncToRestartList(UnifiedRestart, UnifiedInfo);
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 void UnifiedInitLogFile(UnifiedConfig *data)
00991 {
00992 time_t curr_time;
00993 char logdir[STD_BUF];
00994 int value;
00995 UnifiedLogFileHeader hdr;
00996
00997 bzero(logdir, STD_BUF);
00998 curr_time = time(NULL);
00999
01000 if(data == NULL)
01001 {
01002 FatalError("Can't get unified plugin context, that's bad\n");
01003 }
01004
01005 if(*(data->filename) == '/')
01006 value = snprintf(logdir, STD_BUF, "%s.%lu", data->filename,
01007 (unsigned long)curr_time);
01008 else
01009 value = snprintf(logdir, STD_BUF, "%s/%s.%lu", pv.log_dir,
01010 data->filename, (unsigned long)curr_time);
01011
01012 if(value == -1)
01013 {
01014 FatalError("unified log file logging path and file name are "
01015 "too long, aborting!\n");
01016 }
01017
01018 if((data->stream = fopen(logdir, "wb")) == NULL)
01019 {
01020 FatalError("UnifiedInitLogFile(%s): %s\n", logdir, strerror(errno));
01021 }
01022
01023
01024 hdr.magic = LOG_MAGIC;
01025 hdr.version_major = SNORT_VERSION_MAJOR;
01026 hdr.version_minor = SNORT_VERSION_MINOR;
01027 hdr.timezone = thiszone;
01028 hdr.snaplen = snaplen;
01029 hdr.sigfigs = 0;
01030 hdr.linktype = datalink;
01031
01032 #ifdef GIDS
01033 hdr.linktype = DLT_EN10MB;
01034 #endif
01035
01036 if(fwrite((char *)&hdr, sizeof(hdr), 1, data->stream) != 1)
01037 {
01038 FatalError("UnifiedLogInit(): %s", strerror(errno));
01039 }
01040
01041 fflush(data->stream);
01042
01043 return;
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 void OldUnifiedLogPacketAlert(Packet *p, char *msg, void *arg, Event *event)
01059 {
01060 Stream *s = NULL;
01061 StreamPacketData *spd = NULL;
01062 int first_time = 1;
01063 UnifiedLog logheader;
01064 UnifiedConfig *data = (UnifiedConfig *)arg;
01065
01066 if(event != NULL)
01067 {
01068 logheader.event.sig_generator = event->sig_generator;
01069 logheader.event.sig_id = event->sig_id;
01070 logheader.event.sig_rev = event->sig_rev;
01071 logheader.event.classification = event->classification;
01072 logheader.event.priority = event->priority;
01073 logheader.event.event_id = event->event_id;
01074 logheader.event.event_reference = event->event_reference;
01075 logheader.event.ref_time.tv_sec = event->ref_time.tv_sec;
01076 logheader.event.ref_time.tv_usec = event->ref_time.tv_usec;
01077
01078 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "------------\n"););
01079 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "gen: %u\n",
01080 logheader.event.sig_generator););
01081 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "sid: %u\n",
01082 logheader.event.sig_id););
01083 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "rev: %u\n",
01084 logheader.event.sig_rev););
01085 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "cls: %u\n",
01086 logheader.event.classification););
01087 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "pri: %u\n",
01088 logheader.event.priority););
01089 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "eid: %u\n",
01090 logheader.event.event_id););
01091 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "erf: %u\n",
01092 logheader.event.event_reference););
01093 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "sec: %lu\n",
01094 logheader.event.ref_time.tv_sec););
01095 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "usc: %lu\n",
01096 logheader.event.ref_time.tv_usec););
01097 }
01098
01099 if(p->packet_flags & PKT_REBUILT_STREAM)
01100 {
01101 s = (Stream *) p->streamptr;
01102
01103
01104 spd = (StreamPacketData *) ubi_btFirst((ubi_btNodePtr)&s->data);
01105
01106
01107 while (spd != NULL )
01108 {
01109
01110
01111
01112 if(spd->chuck != SEG_UNASSEMBLED)
01113 {
01114 logheader.flags = p->packet_flags;
01115
01116
01117 memcpy(&logheader.pkth, &spd->pkth, sizeof(SnortPktHeader));
01118
01119 #ifdef GIDS
01120
01121
01122
01123
01124
01125
01126 if(!p->eh)
01127 {
01128 logheader.pkth.caplen += sizeof(EtherHdr);
01129 logheader.pkth.pktlen += sizeof(EtherHdr);
01130 }
01131 #endif
01132
01133
01134 if (first_time)
01135 {
01136 logheader.event.ref_time.tv_sec = logheader.pkth.ts.tv_sec;
01137 logheader.event.ref_time.tv_usec = logheader.pkth.ts.tv_usec;
01138 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "sec: %lu\n",
01139 logheader.event.ref_time.tv_sec););
01140 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "usc: %lu\n",
01141 logheader.event.ref_time.tv_usec););
01142
01143 }
01144
01145 if(fwrite((char*)&logheader,sizeof(UnifiedLog),1,data->stream)
01146 != 1)
01147 FatalError("SpoUnified: write failed: %s\n",
01148 strerror(errno));
01149
01150 data->current += sizeof(UnifiedLog);
01151
01152 if(spd->pkt)
01153 {
01154 #ifdef GIDS
01155 if(!p->eh)
01156 {
01157 #ifndef IPFW
01158 memcpy((u_char *)g_ethernet.ether_src,g_m->hw_addr,6);
01159 memset((u_char *)g_ethernet.ether_dst,0x00,6);
01160 #else
01161 memset(g_ethernet.ether_dst,0x00,6);
01162 memset(g_ethernet.ether_src,0x00,6);
01163 #endif
01164 g_ethernet.ether_type = htons(0x0800);
01165
01166 if(fwrite((char*)&g_ethernet,sizeof(EtherHdr),1,data->stream) != 1)
01167 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
01168 data->current += sizeof(EtherHdr);
01169 }
01170 #endif
01171
01172 if(fwrite((char*)spd->pkt,spd->pkth.caplen,1
01173 ,data->stream) != 1)
01174 FatalError("SpoUnified: write failed: %s\n",
01175 strerror(errno));
01176
01177 data->current += spd->pkth.caplen;
01178 }
01179
01180
01181 if (first_time)
01182 {
01183 logheader.event.sig_generator = GENERATOR_TAG;
01184 logheader.event.sig_id = TAG_LOG_PKT;
01185 logheader.event.sig_rev = 1;
01186 logheader.event.classification = 0;
01187 logheader.event.priority = event->priority;
01188 first_time = 0;
01189 }
01190
01191
01192 logheader.event.event_id = ++event_id | pv.event_log_id;
01193 }
01194
01195 spd = (StreamPacketData*) ubi_btNext((ubi_btNodePtr)spd);
01196 }
01197 }
01198 else
01199 {
01200 if(p)
01201 {
01202 logheader.flags = p->packet_flags;
01203
01204 memcpy(&logheader.pkth, p->pkth, sizeof(SnortPktHeader));
01205
01206 #ifdef GIDS
01207
01208
01209
01210
01211
01212
01213 if(!p->eh)
01214 {
01215 logheader.pkth.caplen += sizeof(EtherHdr);
01216 logheader.pkth.pktlen += sizeof(EtherHdr);
01217 }
01218 #endif
01219 }
01220 else
01221 {
01222 logheader.flags = 0;
01223 logheader.pkth.ts.tv_sec = 0;
01224 logheader.pkth.ts.tv_usec = 0;
01225 logheader.pkth.caplen = 0;
01226 logheader.pkth.pktlen = 0;
01227 }
01228
01229 if((data->current + sizeof(UnifiedLog) + logheader.pkth.caplen) >
01230 data->limit)
01231 UnifiedLogRotateFile(data);
01232
01233 fwrite((char*)&logheader, sizeof(UnifiedLog), 1, data->stream);
01234
01235 if(p)
01236 {
01237 #ifdef GIDS
01238 if(!p->eh)
01239 {
01240 #ifndef IPFW
01241 memcpy((u_char *)g_ethernet.ether_src,g_m->hw_addr,6);
01242 memset((u_char *)g_ethernet.ether_dst,0x00,6);
01243 #else
01244 memset(g_ethernet.ether_dst,0x00,6);
01245 memset(g_ethernet.ether_src,0x00,6);
01246 #endif
01247 g_ethernet.ether_type = htons(0x0800);
01248
01249 if(fwrite((char*)&g_ethernet,sizeof(EtherHdr),1,data->stream) != 1)
01250 FatalError("SpoUnified: write failed: %s\n", strerror(errno));
01251 data->current += sizeof(EtherHdr);
01252 }
01253 #endif
01254
01255 fwrite((char*)p->pkt, p->pkth->caplen, 1, data->stream);
01256 }
01257 }
01258
01259 fflush(data->stream);
01260
01261 data->current += sizeof(UnifiedLog) + p->pkth->caplen;
01262
01263 }
01264
01265
01266 void UnifiedLogRotateFile(UnifiedConfig *data)
01267 {
01268
01269 fclose(data->stream);
01270 data->current = 0;
01271 UnifiedInitLogFile(data);
01272 }
01273