Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

event_queue.c

Go to the documentation of this file.
00001 /**
00002 **  @file       event_queue.c
00003 **
00004 **  @author     Daniel Roelker <droelker@sourcefire.com>
00005 **
00006 **  @brief      Snort wrapper to sfeventq library.
00007 **
00008 **  Copyright (C) 2004, Daniel Roelker and Sourcefire, Inc.
00009 **
00010 **  These functions wrap the sfeventq API and provide the priority
00011 **  functions for ordering incoming events.
00012 */
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 #include "fpcreate.h"
00018 #include "fpdetect.h"
00019 #include "util.h"
00020 #include "sfeventq.h"
00021 #include "event_wrapper.h"
00022 #include "event_queue.h"
00023 #include "sfthreshold.h"
00024 
00025 /*
00026 **  Set default values
00027 */
00028 SNORT_EVENT_QUEUE g_event_queue = {8,3,SNORT_EVENTQ_CONTENT_LEN};
00029 
00030 int SnortEventqAdd(unsigned int gid, 
00031                    unsigned int sid, 
00032                    unsigned int rev, 
00033                    unsigned int classification, 
00034                    unsigned int pri,
00035                    char        *msg,
00036                    void        *rule_info)
00037 {
00038     EventNode *en;
00039 
00040     en = (EventNode *)sfeventq_event_alloc();
00041     if(!en)
00042         return -1;
00043 
00044     en->gid = gid;
00045     en->sid = sid;
00046     en->rev = rev;
00047     en->classification = classification;
00048     en->priority = pri;
00049     en->msg = msg;
00050     en->rule_info = rule_info;
00051 
00052     if(sfeventq_add((void *)en))
00053         return -1;
00054 
00055     return 0;
00056 }
00057 
00058 static int OrderPriority(void *event1, void *event2)
00059 {
00060     EventNode *e1;
00061     EventNode *e2;
00062 
00063     if(!event1 || !event2)
00064         return 0;
00065 
00066     e1 = (EventNode *)event1;
00067     e2 = (EventNode *)event2;
00068 
00069     if(e1->priority < e2->priority)
00070         return 1;
00071 
00072     return 0;
00073 }
00074 
00075 static int OrderContentLength(void *event1, void *event2)
00076 {
00077     EventNode *e1;
00078     EventNode *e2;
00079     OTNX      *o1;
00080     OTNX      *o2;
00081 
00082     if(!event1 || !event2)
00083         return 0;
00084 
00085     e1 = (EventNode *)event1;
00086     e2 = (EventNode *)event2;
00087 
00088     if(!e1->rule_info && e2->rule_info)
00089     {
00090         /*
00091         **  incoming event is not a rule, keep
00092         **  looking.
00093         */
00094         return 0;
00095     }
00096     else if(e1->rule_info && !e2->rule_info)
00097     {
00098         /*
00099         **  incoming event is a rule, event in queue
00100         **  is not.  Put incoming here.
00101         */
00102         return 1;
00103     }
00104     else if(!e1->rule_info && !e2->rule_info)
00105     {
00106         /*
00107         **  Neither event is a rule.  Use incoming as
00108         **  priority.  Last one in goes at the end to 
00109         **  preserve rule order.
00110         */
00111         return 0;
00112     }
00113 
00114     /*
00115     **  We already know that these pointers aren't NULL by
00116     **  the previous logic.
00117     */
00118     o1 = (OTNX *)e1->rule_info;
00119     o2 = (OTNX *)e2->rule_info;
00120 
00121     if(o1->content_length > o2->content_length)
00122         return 1;
00123 
00124     return 0;
00125 }
00126 
00127 int SnortEventqInit(void)
00128 {
00129     int (*sort)(void *, void*) = NULL;
00130 
00131     if(g_event_queue.order == SNORT_EVENTQ_PRIORITY)
00132     {
00133         sort = OrderPriority;
00134     }
00135     else if(g_event_queue.order == SNORT_EVENTQ_CONTENT_LEN)
00136     {
00137         sort = OrderContentLength;
00138     }
00139     else
00140     {
00141         FatalError("Order function for event queue is invalid.\n");
00142     }
00143         
00144     if(sfeventq_init(g_event_queue.max_events, g_event_queue.log_events,
00145                     sizeof(EventNode), sort))
00146     {
00147         FatalError("Failed to initialize Snort event queue.\n");
00148     }
00149 
00150     return 0;
00151 }
00152             
00153 static int LogSnortEvents(void *event, void *user)
00154 {
00155     Packet    *p;
00156     EventNode *en;
00157     OTNX      *otnx;
00158     SNORT_EVENTQ_USER *snort_user;
00159 
00160     if(!event || !user)
00161         return 0;
00162 
00163     en         = (EventNode *)event;
00164     snort_user = (SNORT_EVENTQ_USER *)user;
00165     p  = (Packet *)snort_user->pkt;
00166 
00167     /*
00168     **  Log rule events differently because we have to.
00169     */
00170     if(en->rule_info)
00171     {
00172         otnx = (OTNX *)en->rule_info;
00173         if(!otnx->rtn || !otnx->otn)
00174             return 0;
00175 
00176         snort_user->rule_alert = 1;
00177 
00178         fpLogEvent(otnx->rtn, otnx->otn, p);
00179     }
00180     else
00181     {
00182         GenerateSnortEvent(p, en->gid, en->sid, en->rev,
00183                            en->classification, en->priority, en->msg);
00184     }
00185 
00186     sfthreshold_reset();
00187 
00188     return 0;
00189 }
00190 
00191 /*
00192 **  NAME
00193 **    SnortEventqLog::
00194 */
00195 /**
00196 **  We return whether we logged events or not.  We've add a eventq user
00197 **  structure so we can track whether the events logged we're rule events
00198 **  or preprocessor/decoder events.  The reason being that we don't want
00199 **  to flush a TCP stream for preprocessor/decoder events, and cause
00200 **  early flushing of the stream.
00201 **
00202 **  @return 1 logged events
00203 **  @return 0 did not log events or logged only decoder/preprocessor events
00204 */
00205 int SnortEventqLog(Packet *p)
00206 {
00207     static SNORT_EVENTQ_USER user;
00208 
00209     user.rule_alert = 0x00;
00210     user.pkt = (void *)p;
00211 
00212     if(sfeventq_action(LogSnortEvents, (void *)&user) > 0)
00213     {
00214         if(user.rule_alert)
00215             return 1;
00216     }
00217 
00218     return 0;
00219 }
00220 
00221 void SnortEventqReset(void)
00222 {
00223     sfeventq_reset();
00224     return;
00225 }

Generated on Sun May 14 14:51:13 2006 by  doxygen 1.4.2