1 /* $Id$ */
2 /*
3 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
4 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
5 ** Copyright (C) 2002-2013 Sourcefire, Inc.
6 **    Dan Roelker <droelker@sourcefire.com>
7 **    Marc Norton <mnorton@sourcefire.com>
8 **
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License Version 2 as
11 ** published by the Free Software Foundation.  You may not use, modify or
12 ** distribute this program under any other version of the GNU General
13 ** Public License.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23 **
24 ** NOTES
25 **   5.7.02: Added interface for new detection engine. (Norton/Roelker)
26 **
27 */
28 
29 #define FASTPKT
30 
31 /*  I N C L U D E S  **********************************************/
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35 
36 #include <string.h>
37 #include <stdlib.h>
38 
39 #include "snort.h"
40 #include "detect.h"
41 #include "plugbase.h"
42 #include "snort_debug.h"
43 #include "util.h"
44 #include "mstring.h"
45 #include "tag.h"
46 #include "pcrm.h"
47 #include "fpcreate.h"
48 #include "fpdetect.h"
49 #include "sfthreshold.h"
50 #include "event_wrapper.h"
51 #include "event_queue.h"
52 #include "obfuscation.h"
53 #include "profiler.h"
54 #include "session_api.h"
55 #include "session_common.h"
56 #include "stream_api.h"
57 #include "snort_stream_udp.h"
58 #include "active.h"
59 #include "signature.h"
60 #include "ipv6_port.h"
61 #include "ppm.h"
62 #include "sf_types.h"
63 #include "active.h"
64 #include "detection_util.h"
65 #include "preprocids.h"
66 #if defined(FEAT_OPEN_APPID)
67 #include "sp_appid.h"
68 #include "appIdApi.h"
69 #endif /* defined(FEAT_OPEN_APPID) */
70 
71 #ifdef PORTLISTS
72 #include "sfutil/sfportobject.h"
73 #endif
74 #ifdef PERF_PROFILING
75 PreprocStats detectPerfStats;
76 #endif
77 
78 #ifdef TARGET_BASED
79 #include "target-based/sftarget_protocol_reference.h"
80 #endif
81 #include "sfPolicy.h"
82 
83 /* #define ITERATIVE_ENGINE */
84 
85 
86 OptTreeNode *otn_tmp = NULL;       /* OptTreeNode temp ptr */
87 
88 int do_detect;
89 int do_detect_content;
90 uint16_t event_id;
91 static char check_tags_flag;
92 
93 static int CheckTagging(Packet *);
94 
95 #ifdef PERF_PROFILING
96 PreprocStats eventqPerfStats;
97 #endif
98 
preprocHandlesProto(Packet * p,PreprocEvalFuncNode * ppn)99 static inline int preprocHandlesProto( Packet *p, PreprocEvalFuncNode *ppn )
100 {
101     return ( ( p->proto_bits & ppn->proto_mask ) || ( ppn->proto_mask == PROTO_BIT__ALL ) );
102 }
103 
processDecoderAlertsActionQ(Packet * p)104 static inline bool processDecoderAlertsActionQ( Packet *p )
105 {
106     // with policy selected, process any decoder alerts and queued actions
107     DecodePolicySpecific(p);
108     // actions are queued only for IDS case
109     sfActionQueueExecAll(decoderActionQ);
110     return true;
111 }
112 
DispatchPreprocessors(Packet * p,tSfPolicyId policy_id,SnortPolicy * policy)113 static void DispatchPreprocessors( Packet *p, tSfPolicyId policy_id, SnortPolicy *policy )
114 {
115     SessionControlBlock *scb = NULL;
116     PreprocEvalFuncNode *ppn;
117     PreprocEnableMask pps_enabled_foo;
118     bool alerts_processed = false;
119 
120 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
121     uint64_t start=0, end=0;
122 #endif
123 
124     // No expected sessions yet.
125     p->expectedSession = NULL;
126 
127     // until we are in a Session context dispatch preprocs from the policy list if there is one
128     p->cur_pp = policy->preproc_eval_funcs;
129     if( p->cur_pp == NULL )
130     {
131         alerts_processed = processDecoderAlertsActionQ( p );
132         LogMessage("WARNING: No preprocessors configured for policy %d.\n", policy_id);
133         return;
134     }
135 
136     pps_enabled_foo = policy->pp_enabled[ p->dp ] | policy->pp_enabled[ p->sp ];
137     EnablePreprocessors( p, pps_enabled_foo );
138     do {
139         ppn = p->cur_pp;
140         p->cur_pp = ppn->next;
141 
142         // if packet has no data and we are up to APP preprocs then get out
143         if( p->dsize == 0 && ppn->priority >= PRIORITY_APPLICATION )
144             break;
145 
146         if ( preprocHandlesProto( p, ppn ) && IsPreprocessorEnabled( p, ppn->preproc_bit ) )
147         {
148 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
149             if (p->pkth && (p->pkth->flags & DAQ_PKT_FLAG_DEBUG_ON))
150             {
151                 get_clockticks(start);
152                 ppn->func( p, ppn->context );
153                 get_clockticks(end);
154                 print_flow(p,NULL,ppn->preproc_id,start,end);
155             }
156             else
157                 ppn->func( p, ppn->context );
158 #else
159             ppn->func( p, ppn->context );
160 #endif
161         }
162 
163 
164         if( !alerts_processed && ( p->ips_os_selected || ppn->preproc_id == PP_FW_RULE_ENGINE ) )
165             alerts_processed = processDecoderAlertsActionQ( p );
166 
167         if( scb == NULL && p->ssnptr != NULL )
168             scb = ( SessionControlBlock * ) p->ssnptr;
169         // if we now have session, update enabled pps if changed by previous preproc
170         if( scb != NULL && pps_enabled_foo != scb->enabled_pps )
171         {
172             EnablePreprocessors( p, scb->enabled_pps );
173             pps_enabled_foo = scb->enabled_pps;
174         }
175 
176         if( ( ppn->preproc_id == PP_FW_RULE_ENGINE ) &&
177             ( ( IPH_IS_VALID( p ) ) && ( GET_IPH_PROTO( p ) == IPPROTO_UDP ) ) &&
178             ( session_api->protocol_tracking_enabled( SESSION_PROTO_UDP ) ) )
179         {
180             InspectPortFilterUdp( p );
181         }
182 
183     } while ( ( p->cur_pp != NULL ) && !( p->packet_flags & PKT_PASS_RULE ) );
184 
185     // queued decoder alerts are processed after the selection of the
186     // IPS rule config for the flow, if not yet done then process them now
187     if( !alerts_processed )
188         alerts_processed = processDecoderAlertsActionQ( p );
189 
190     if( p->dsize == 0 )
191         DisableDetect( p );
192 }
193 
194 
Preprocess(Packet * p)195 int Preprocess(Packet * p)
196 {
197     int retval = 0;
198     int detect_retval = 0;
199     tSfPolicyId policy_id;
200 
201    /* NAP runtime policy may have been updated during decode,
202     * but preprocess needs default nap policy for session
203     * preprocessor selection, hence use default policy when
204     * called without session pointer set.
205     */
206     if( !p->ssnptr )
207         policy_id = getDefaultPolicy();
208     else
209         policy_id = getNapRuntimePolicy();
210 
211     SnortPolicy *policy = snort_conf->targeted_policies[policy_id];
212 #ifdef PPM_MGR
213     uint64_t pktcnt=0;
214 #endif
215     PROFILE_VARS;
216 
217     if (policy == NULL)
218         return -1;
219 
220 #ifdef PPM_MGR
221     /* Begin Packet Performance Monitoring  */
222     if( PPM_PKTS_ENABLED() )
223     {
224         pktcnt = PPM_INC_PKT_CNT();
225         PPM_GET_TIME();
226         PPM_INIT_PKT_TIMER();
227 #ifdef DEBUG
228         if( PPM_DEBUG_PKTS() )
229         {
230            /* for debugging, info gathering, so don't worry about
231            *  (unsigned) casting of pktcnt, were not likely to debug
232            *  4G packets
233            */
234            LogMessage("PPM: Process-BeginPkt[%u] caplen=%u\n",
235              (unsigned)pktcnt,p->pkth->caplen);
236         }
237 #endif
238     }
239 #endif
240 
241     // If the packet has errors or syn over rate, we won't analyze it.
242     if ( p->error_flags )
243     {
244         // process any decoder alerts now that policy has been selected...
245         DecodePolicySpecific(p);
246 
247         //actions are queued only for IDS case
248         sfActionQueueExecAll(decoderActionQ);
249         DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
250             "Packet errors = 0x%x, ignoring traffic!\n", p->error_flags););
251 
252         if ( p->error_flags & PKT_ERR_BAD_TTL )
253             pc.bad_ttl++;
254         else if( p->error_flags & PKT_ERR_SYN_RL_DROP )
255             pc.syn_rate_limit_drops++;
256         else
257             pc.invalid_checksums++;
258     }
259     else
260     {
261         /* Not a completely ideal place for this since any entries added on the
262          * PacketCallback -> ProcessPacket -> Preprocess trail will get
263          * obliterated - right now there isn't anything adding entries there.
264          * Really need it here for stream5 clean exit, since all of the
265          * flushed, reassembled packets are going to be injected directly into
266          * this function and there may be enough that the obfuscation entry
267          * table will overflow if we don't reset it.  Putting it here does
268          * have the advantage of fewer entries per logging cycle */
269         obApi->resetObfuscationEntries();
270 
271         do_detect = do_detect_content = !snort_conf->disable_all_policies;
272 
273         /*
274         **  Reset the appropriate application-layer protocol fields
275         */
276         ClearHttpBuffers();
277         p->alt_dsize = 0;
278         DetectReset(p->data, p->dsize);
279 
280         // ok, dispatch all preprocs enabled for this packet/session
281         DispatchPreprocessors( p, policy_id, policy );
282 
283         if ( do_detect )
284         {
285             detect_retval = Detect(p);
286         }
287     }
288 
289     check_tags_flag = 1;
290 
291 #ifdef DUMP_BUFFER
292     dumped_state = false;
293 #endif
294 
295     PREPROC_PROFILE_START(eventqPerfStats);
296     retval = SnortEventqLog(snort_conf->event_queue, p);
297 
298 #ifdef DUMP_BUFFER
299 
300     /* dump_alert_only makes sure that bufferdump happens only when a rule is
301     triggered.
302 
303     dumped_state avoids repetition of buffer dump for a packet that has an
304     alert, when --buffer-dump is given as command line option.
305 
306     When --buffer-dump is given as command line option, BufferDump output
307     plugin is called for each packet. bdfptr will be NULL for all other output
308     plugins.
309     */
310 
311     if (!dump_alert_only && !dumped_state)
312     {
313          OutputFuncNode *idx = LogList;
314 
315          while (idx != NULL)
316          {
317              if (idx->bdfptr != NULL)
318                  idx->bdfptr(p, NULL , idx->arg, NULL);
319 
320              idx = idx->next;
321          }
322      }
323 #endif
324 
325     SnortEventqReset();
326     PREPROC_PROFILE_END(eventqPerfStats);
327 
328     /* Check for normally closed session */
329     if( session_api )
330         session_api->check_session_closed(p);
331 
332     if( session_api && p->ssnptr &&
333       ( session_api->get_session_flags(p->ssnptr) & SSNFLAG_FREE_APP_DATA) )
334     {
335         SessionControlBlock *scb = ( SessionControlBlock * ) p->ssnptr;
336         session_api->free_application_data(scb);
337         scb->ha_state.session_flags &= ~SSNFLAG_FREE_APP_DATA;
338     }
339 
340     /*
341     ** By checking tagging here, we make sure that we log the
342     ** tagged packet whether it generates an alert or not.
343     */
344     if (IPH_IS_VALID(p))
345         CheckTagging(p);
346 
347     otn_tmp = NULL;
348 
349     /*
350     **  If we found events in this packet, let's flush
351     **  the stream to make sure that we didn't miss any
352     **  attacks before this packet.
353     */
354     if(retval && IsTCP(p) && stream_api)
355         stream_api->alert_flush_stream(p);
356 
357 #ifdef PPM_MGR
358     if( PPM_PKTS_ENABLED() )
359     {
360         PPM_GET_TIME();
361         PPM_TOTAL_PKT_TIME();
362         PPM_ACCUM_PKT_TIME();
363 #ifdef DEBUG
364         if( PPM_DEBUG_PKTS() )
365         {
366             LogMessage("PPM: Pkt[%u] Used= ",(unsigned)pktcnt);
367             PPM_PRINT_PKT_TIME("%g usecs\n");
368             LogMessage("PPM: Process-EndPkt[%u]\n\n",(unsigned)pktcnt);
369         }
370 #endif
371        // When detection is required to happen and it is skipped , then only we will print the trace.
372         if (do_detect && (!detect_retval))
373             PPM_LATENCY_TRACE();
374 
375         PPM_PKT_LOG(p);
376     }
377     if( PPM_RULES_ENABLED() )
378     {
379         PPM_RULE_LOG(pktcnt, p);
380     }
381     if( PPM_PKTS_ENABLED() )
382     {
383         PPM_END_PKT_TIMER();
384     }
385 #endif
386 
387     return retval;
388 }
389 
390 /*
391 **  NAME
392 **    CheckTagging::
393 */
394 /**
395 **  This is where we check to see if we tag the packet.  We only do
396 **  this if we've alerted on a non-pass rule and the packet is not
397 **  rebuilt.
398 **
399 **  We don't log rebuilt packets because the output plugins log the
400 **  individual packets of a rebuilt stream, so we don't want to dup
401 **  tagged packets for rebuilt streams.
402 **
403 **  @return integer
404 */
CheckTagging(Packet * p)405 static int CheckTagging(Packet *p)
406 {
407     Event event;
408 
409     if(check_tags_flag == 1 && !(p->packet_flags & PKT_REBUILT_STREAM))
410     {
411         void* listhead = NULL;
412         DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "calling CheckTagList\n"););
413 
414         if(CheckTagList(p, &event, &listhead))
415         {
416             DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Matching tag node found, "
417                         "calling log functions\n"););
418 
419             /* if we find a match, we want to send the packet to the
420              * logging mechanism
421              */
422             CallLogFuncs(p, "Tagged Packet", listhead, &event);
423         }
424     }
425 
426     return 0;
427 }
428 
429 #if defined(FEAT_OPEN_APPID)
updateEventAppName(Packet * p,OptTreeNode * otn,Event * event)430 static void updateEventAppName (Packet *p, OptTreeNode *otn, Event *event)
431 {
432     const char *appName;
433     size_t appNameLen;
434     AppIdOptionData *app_data = (AppIdOptionData*)otn->ds_list[PLUGIN_APPID];
435 
436     if (app_data && (app_data->matched_appid) && (appName = appIdApi.getApplicationName(app_data->matched_appid)))
437     {
438         appNameLen = strlen(appName);
439         if (appNameLen >= sizeof(event->app_name))
440             appNameLen = sizeof(event->app_name) - 1;
441         memcpy(event->app_name, appName, appNameLen);
442         event->app_name[appNameLen] = '\0';
443     }
444     else if (p->ssnptr)
445     {
446         //log most specific appid when rule didn't have any appId
447         int16_t serviceProtoId, clientProtoId, payloadProtoId, miscProtoId, pickedProtoId;
448 
449         stream_api->get_application_id(p->ssnptr, &serviceProtoId, &clientProtoId, &payloadProtoId, &miscProtoId);
450         if ((p->packet_flags & PKT_FROM_CLIENT))
451         {
452             if (!(pickedProtoId = payloadProtoId) &&  !(pickedProtoId = miscProtoId) && !(pickedProtoId = clientProtoId))
453                 pickedProtoId = serviceProtoId;
454         }
455         else
456         {
457             if (!(pickedProtoId = payloadProtoId) &&  !(pickedProtoId = miscProtoId) && !(pickedProtoId = serviceProtoId))
458                 pickedProtoId = clientProtoId;
459         }
460 
461         if ((pickedProtoId) && (appName = appIdApi.getApplicationName(pickedProtoId)))
462         {
463             appNameLen = strlen(appName);
464             if (appNameLen >= sizeof(event->app_name))
465                 appNameLen = sizeof(event->app_name) - 1;
466             memcpy(event->app_name, appName, appNameLen);
467             event->app_name[appNameLen] = '\0';
468         }
469         else
470         {
471             event->app_name[0] = 0;
472         }
473     }
474     else
475     {
476         event->app_name[0] = 0;
477     }
478 }
479 #endif /* defined(FEAT_OPEN_APPID) */
CallLogFuncs(Packet * p,const char * message,ListHead * head,Event * event)480 void CallLogFuncs(Packet *p, const char *message, ListHead *head, Event *event)
481 {
482     OutputFuncNode *idx = NULL;
483 
484     if (event->sig_generator != GENERATOR_TAG)
485     {
486         event->ref_time.tv_sec = p->pkth->ts.tv_sec;
487         event->ref_time.tv_usec = p->pkth->ts.tv_usec;
488     }
489     /* set the event number */
490     event->event_id = event_id | ScEventLogId();
491 
492     check_tags_flag = 0;
493 
494     pc.log_pkts++;
495 
496     if ( head == NULL || head->LogList == NULL )
497     {
498         CallLogPlugins(p, message, event);
499         return;
500     }
501 
502     idx = head->LogList;
503     while ( idx != NULL )
504     {
505         idx->func(p, message, idx->arg, event);
506         idx = idx->next;
507     }
508 }
509 
CallLogPlugins(Packet * p,const char * message,Event * event)510 void CallLogPlugins(Packet * p, const char *message, Event *event)
511 {
512     OutputFuncNode *idx = LogList;
513 
514     while ( idx != NULL )
515     {
516         idx->func(p, message, idx->arg, event);
517         idx = idx->next;
518     }
519 }
520 
521 /* Call the output functions that are directly attached to the signature */
CallSigOutputFuncs(Packet * p,OptTreeNode * otn,Event * event)522 void CallSigOutputFuncs(Packet *p, OptTreeNode *otn, Event *event)
523 {
524     OutputFuncNode *idx = NULL;
525 
526     idx = otn->outputFuncs;
527 
528     while(idx)
529     {
530         idx->func(p, otn->sigInfo.message, idx->arg, event);
531         idx = idx->next;
532     }
533 }
534 
CallAlertFuncs(Packet * p,const char * message,ListHead * head,Event * event)535 void CallAlertFuncs(Packet * p, const char *message, ListHead * head, Event *event)
536 {
537     OutputFuncNode *idx = NULL;
538 
539     event->ref_time.tv_sec = p->pkth->ts.tv_sec;
540     event->ref_time.tv_usec = p->pkth->ts.tv_usec;
541 
542     /* set the event number */
543     event->event_id = event_id | ScEventLogId();
544     /* set the event reference info */
545     event->event_reference = event->event_id;
546 
547     pc.total_alert_pkts++;
548 
549     if ( event->sig_generator != GENERATOR_SPP_REPUTATION )
550     {
551         /* Don't include IP Reputation events in count */
552         pc.alert_pkts++;
553     }
554 
555     if ( head == NULL || head->AlertList == NULL )
556     {
557         CallAlertPlugins(p, message, event);
558         return;
559     }
560 
561     idx = head->AlertList;
562     while ( idx != NULL )
563     {
564         idx->func(p, message, idx->arg, event);
565         idx = idx->next;
566     }
567 }
568 
569 
CallAlertPlugins(Packet * p,const char * message,Event * event)570 void CallAlertPlugins(Packet * p, const char *message, Event *event)
571 {
572     OutputFuncNode *idx = AlertList;
573 
574     while ( idx != NULL )
575     {
576         idx->func(p, message, idx->arg, event);
577         idx = idx->next;
578     }
579 }
580 
581 /****************************************************************************
582  *
583  * Function: Detect(Packet *)
584  *
585  * Purpose: Apply the rules lists to the current packet
586  *
587  * Arguments: p => ptr to the decoded packet struct
588  *
589  * Returns: 1 == detection event
590  *          0 == no detection
591  *
592  ***************************************************************************/
Detect(Packet * p)593 int Detect(Packet * p)
594 {
595     int detected = 0;
596     PROFILE_VARS;
597 
598 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
599     uint64_t start = 0, end = 0;
600 #endif
601 
602     if ((p == NULL) || !IPH_IS_VALID(p))
603     {
604         return 0;
605     }
606 
607     if (stream_api && stream_api->is_session_http2(p->ssnptr)
608         && !(p->packet_flags & PKT_REBUILT_STREAM)
609         && !(p->packet_flags & PKT_PDU_TAIL))
610     {
611         return 0;
612     }
613 
614     if (!snort_conf->ip_proto_array[GET_IPH_PROTO(p)])
615     {
616 #ifdef GRE
617         switch (p->outer_family)
618         {
619             case AF_INET:
620                 if (!snort_conf->ip_proto_array[p->outer_ip4h.ip_proto])
621                     return 0;
622                 break;
623 
624             case AF_INET6:
625                 if (!snort_conf->ip_proto_array[p->outer_ip6h.next])
626                     return 0;
627                 break;
628 
629             default:
630                 return 0;
631         }
632 #else
633         return 0;
634 #endif  /* GRE */
635     }
636 
637     if (p->packet_flags & PKT_PASS_RULE)
638     {
639         /* If we've already seen a pass rule on this,
640          * no need to continue do inspection.
641          */
642         return 0;
643     }
644 
645 #ifdef PPM_MGR
646     /*
647      * Packet Performance Monitoring
648      * (see if preprocessing took too long)
649      */
650     if( PPM_PKTS_ENABLED() )
651     {
652         PPM_GET_TIME();
653         PPM_PACKET_TEST();
654 
655         if( PPM_PACKET_ABORT_FLAG() )
656             return 0;
657     }
658 #endif
659 
660     /*
661     **  This is where we short circuit so
662     **  that we can do IP checks.
663     */
664     PREPROC_PROFILE_START(detectPerfStats);
665  #if defined(DAQ_VERSION) && DAQ_VERSION > 9
666     if (p->pkth && (p->pkth->flags & DAQ_PKT_FLAG_DEBUG_ON))
667     {
668         get_clockticks(start);
669         detected = fpEvalPacket(p);
670         get_clockticks(end);
671         print_flow(p,"DETECTION",0,start,end);
672     }
673     else
674         detected = fpEvalPacket(p);
675  #else
676     detected = fpEvalPacket(p);
677 #endif
678 
679     PREPROC_PROFILE_END(detectPerfStats);
680 
681     return detected;
682 }
683 
TriggerResponses(Packet * p,OptTreeNode * otn)684 void TriggerResponses(Packet * p, OptTreeNode * otn)
685 {
686 
687     RspFpList *idx;
688 
689     idx = otn->rsp_func;
690 
691     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"Triggering responses %p\n", idx););
692 
693     while(idx != NULL)
694     {
695         idx->func(p, idx->params);
696         idx = idx->next;
697     }
698 
699 }
700 
CheckAddrPort(sfip_var_t * rule_addr,PortObject * po,Packet * p,uint32_t flags,int mode)701 int CheckAddrPort(
702                 sfip_var_t *rule_addr,
703                 PortObject * po,
704                 Packet *p,
705                 uint32_t flags, int mode)
706 {
707     sfaddr_t* pkt_addr;              /* packet IP address */
708     u_short pkt_port;                /* packet port */
709     int global_except_addr_flag = 0; /* global exception flag is set */
710     int any_port_flag = 0;           /* any port flag set */
711     int except_port_flag = 0;        /* port exception flag set */
712     int ip_match = 0;                /* flag to indicate addr match made */
713 
714     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "CheckAddrPort: "););
715     /* set up the packet particulars */
716     if(mode & CHECK_SRC_IP)
717     {
718         pkt_addr = GET_SRC_IP(p);
719         pkt_port = p->sp;
720 
721         DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"SRC "););
722 
723         if(mode & INVERSE)
724         {
725             global_except_addr_flag = flags & EXCEPT_DST_IP;
726             any_port_flag = flags & ANY_DST_PORT;
727             except_port_flag = flags & EXCEPT_DST_PORT;
728         }
729         else
730         {
731             global_except_addr_flag = flags & EXCEPT_SRC_IP;
732             any_port_flag = flags & ANY_SRC_PORT;
733             except_port_flag = flags & EXCEPT_SRC_PORT;
734         }
735     }
736     else
737     {
738         pkt_addr = GET_DST_IP(p);
739         pkt_port = p->dp;
740 
741         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "DST "););
742 
743         if(mode & INVERSE)
744         {
745             global_except_addr_flag = flags & EXCEPT_SRC_IP;
746             any_port_flag = flags & ANY_SRC_PORT;
747             except_port_flag = flags & EXCEPT_SRC_PORT;
748         }
749         else
750         {
751             global_except_addr_flag = flags & EXCEPT_DST_IP;
752             any_port_flag = flags & ANY_DST_PORT;
753             except_port_flag = flags & EXCEPT_DST_PORT;
754         }
755     }
756 
757     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "addr %lx, port %d ", pkt_addr,
758                 pkt_port););
759 
760     if(!rule_addr)
761         goto bail;
762 
763     if(!(global_except_addr_flag)) /*modeled after Check{Src,Dst}IP function*/
764     {
765         if(sfvar_ip_in(rule_addr, pkt_addr))
766             ip_match = 1;
767     }
768     else
769     {
770         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", global exception flag set"););
771         /* global exception flag is up, we can't match on *any*
772          * of the source addresses
773          */
774 
775         if(sfvar_ip_in(rule_addr, pkt_addr))
776             return 0;
777 
778         ip_match=1;
779     }
780 
781 bail:
782     if(!ip_match)
783     {
784         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", no address match,  "
785                     "packet rejected\n"););
786         return 0;
787     }
788 
789     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", addresses accepted"););
790 
791     /* if the any port flag is up, we're all done (success) */
792     if(any_port_flag)
793     {
794         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", any port match, "
795                     "packet accepted\n"););
796         return 1;
797     }
798 
799 #ifdef TARGET_BASED
800     if (!(mode & (CHECK_SRC_PORT | CHECK_DST_PORT)))
801     {
802         DEBUG_WRAP(
803             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckAddrPort..."
804                 "target-based-protocol=%d,ignoring ports\n",
805                 GetProtocolReference(p)););
806         return 1;
807     }
808     else
809     {
810         DEBUG_WRAP(
811             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckAddrPort..."
812                 "target-based-protocol=%d,not ignoring ports\n",
813                 GetProtocolReference(p)););
814     }
815 #endif /* TARGET_BASED */
816 
817     /* check the packet port against the rule port */
818     if( !PortObjectHasPort(po,pkt_port) )
819     {
820         /* if the exception flag isn't up, fail */
821         if(!except_port_flag)
822         {
823             DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", port mismatch,  "
824                         "packet rejected\n"););
825             return 0;
826         }
827         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", port mismatch exception"););
828     }
829     else
830     {
831         /* if the exception flag is up, fail */
832         if(except_port_flag)
833         {
834             DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
835                                     ", port match exception,  packet rejected\n"););
836             return 0;
837         }
838         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", ports match"););
839     }
840 
841     /* ports and address match */
842     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", packet accepted!\n"););
843     return 1;
844 
845 }
846 
847 /****************************************************************************
848  *
849  * Function: DumpList(IpAddrNode*)
850  *
851  * Purpose: print out the chain lists by header block node group
852  *
853  * Arguments: node => the head node
854  *
855  * Returns: void function
856  *
857  ***************************************************************************/
DumpList(IpAddrNode * idx,int negated)858 void DumpList(IpAddrNode *idx, int negated)
859 {
860     DEBUG_WRAP(int i=0;);
861     if(!idx)
862         return;
863 
864     while(idx != NULL)
865     {
866        DEBUG_WRAP(DebugMessage(DEBUG_RULES,
867                         "[%d]    %s",
868                         i++, sfip_ntoa(&idx->ip->addr)););
869 
870        if(negated)
871        {
872            DEBUG_WRAP(DebugMessage(DEBUG_RULES,
873                        "    (EXCEPTION_FLAG Active)\n"););
874        }
875        else
876        {
877            DEBUG_WRAP(DebugMessage(DEBUG_RULES, "\n"););
878        }
879 
880        idx = idx->next;
881     }
882 }
883 
884 
885 /****************************************************************************
886  *
887  * Function: DumpChain(RuleTreeNode *, char *, char *)
888  *
889  * Purpose: Iterate over RTNs calling DumpList on each
890  *
891  * Arguments: rtn_idx => the RTN index pointer
892  *                       rulename => the name of the rule the list belongs to
893  *            listname => the name of the list being printed out
894  *
895  * Returns: void function
896  *
897  ***************************************************************************/
DumpChain(RuleTreeNode * rtn_head,char * rulename,char * listname)898 void DumpChain(RuleTreeNode * rtn_head, char *rulename, char *listname)
899 {
900     // XXX Not yet implemented - Rule chain dumping
901 }
902 
903 #define CHECK_ADDR_SRC_ARGS(x) (x)->src_portobject
904 #define CHECK_ADDR_DST_ARGS(x) (x)->dst_portobject
905 
CheckBidirectional(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)906 int CheckBidirectional(Packet *p, struct _RuleTreeNode *rtn_idx,
907         RuleFpList *fp_list, int check_ports)
908 {
909     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Checking bidirectional rule...\n"););
910 
911     if(CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p,
912                      rtn_idx->flags, CHECK_SRC_IP | (check_ports ? CHECK_SRC_PORT : 0)))
913     {
914         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "   Src->Src check passed\n"););
915         if(! CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p,
916                            rtn_idx->flags, CHECK_DST_IP | (check_ports ? CHECK_DST_PORT : 0)))
917         {
918             DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
919                                     "   Dst->Dst check failed,"
920                                     " checking inverse combination\n"););
921             if(CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p,
922                              rtn_idx->flags, (CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0))))
923             {
924                 DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
925                                     "   Inverse Dst->Src check passed\n"););
926                 if(!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p,
927                                   rtn_idx->flags, (CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0))))
928                 {
929                     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
930                                     "   Inverse Src->Dst check failed\n"););
931                     return 0;
932                 }
933                 else
934                 {
935                     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Inverse addr/port match\n"););
936                 }
937             }
938             else
939             {
940                 DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "   Inverse Dst->Src check failed,"
941                                         " trying next rule\n"););
942                 return 0;
943             }
944         }
945         else
946         {
947             DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "dest IP/port match\n"););
948         }
949     }
950     else
951     {
952         DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
953                                 "   Src->Src check failed, trying inverse test\n"););
954         if(CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p,
955                          rtn_idx->flags, CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0)))
956         {
957             DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
958                         "   Dst->Src check passed\n"););
959 
960             if(!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p,
961                         rtn_idx->flags, CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0)))
962             {
963                 DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
964                             "   Src->Dst check failed\n"););
965                 return 0;
966             }
967             else
968             {
969                 DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
970                             "Inverse addr/port match\n"););
971             }
972         }
973         else
974         {
975             DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"   Inverse test failed, "
976                         "testing next rule...\n"););
977             return 0;
978         }
979     }
980 
981     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"   Bidirectional success!\n"););
982     return 1;
983 }
984 
985 
986 /****************************************************************************
987  *
988  * Function: CheckSrcIp(Packet *, struct _RuleTreeNode *, RuleFpList *)
989  *
990  * Purpose: Test the source IP and see if it equals the SIP of the packet
991  *
992  * Arguments: p => ptr to the decoded packet data structure
993  *            rtn_idx => ptr to the current rule data struct
994  *            fp_list => ptr to the current function pointer node
995  *
996  * Returns: 0 on failure (no match), 1 on success (match)
997  *
998  ***************************************************************************/
CheckSrcIP(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)999 int CheckSrcIP(Packet * p, struct _RuleTreeNode * rtn_idx, RuleFpList * fp_list, int check_ports)
1000 {
1001 
1002     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcIPEqual: "););
1003 
1004     if(!(rtn_idx->flags & EXCEPT_SRC_IP))
1005     {
1006         if( sfvar_ip_in(rtn_idx->sip, GET_SRC_IP(p)) )
1007         {
1008 // XXX NOT YET IMPLEMENTED - debugging in Snort6
1009 #if 0
1010 #ifdef DEBUG_MSGS
1011             sfaddr_t ip;
1012             if(idx->addr_flags & EXCEPT_IP) {
1013                 DebugMessage(DEBUG_DETECT, "  SIP exception match\n");
1014             }
1015             else
1016             {
1017                 DebugMessage(DEBUG_DETECT, "  SIP match\n");
1018             }
1019 
1020             ip = *iph_ret_src(p);    /* necessary due to referencing/dereferencing */
1021             DebugMessage(DEBUG_DETECT, "Rule: %s     Packet: %s\n",
1022                    inet_ntoa(idx->ip_addr), inet_ntoa(ip));
1023 #endif /* DEBUG */
1024 #endif
1025 
1026             /* the packet matches this test, proceed to the next test */
1027             return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1028         }
1029     }
1030     else
1031     {
1032         /* global exception flag is up, we can't match on *any*
1033          * of the source addresses
1034          */
1035         DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"  global exception flag, \n"););
1036 
1037         if( sfvar_ip_in(rtn_idx->sip, GET_SRC_IP(p)) ) return 0;
1038 
1039         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1040     }
1041 
1042     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"  Mismatch on SIP\n"););
1043 
1044     return 0;
1045 
1046     /* return 0 on a failed test */
1047     return 0;
1048 }
1049 
1050 
1051 /****************************************************************************
1052  *
1053  * Function: CheckDstIp(Packet *, struct _RuleTreeNode *, RuleFpList *)
1054  *
1055  * Purpose: Test the dest IP and see if it equals the DIP of the packet
1056  *
1057  * Arguments: p => ptr to the decoded packet data structure
1058  *            rtn_idx => ptr to the current rule data struct
1059  *            fp_list => ptr to the current function pointer node
1060  *
1061  * Returns: 0 on failure (no match), 1 on success (match)
1062  *
1063  ***************************************************************************/
CheckDstIP(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)1064 int CheckDstIP(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports)
1065 {
1066 
1067     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "CheckDstIPEqual: ");)
1068 
1069     if(!(rtn_idx->flags & EXCEPT_DST_IP))
1070     {
1071         if( sfvar_ip_in(rtn_idx->dip, GET_DST_IP(p)) )
1072         {
1073 // #ifdef DEBUG_MSGS
1074 // XXX idx's equivalent is lost inside of sfvar_ip_in
1075 //            DebugMessage(DEBUG_DETECT, "Rule: %s     Packet: ",
1076 //                   inet_ntoa(idx->ip_addr));
1077 //            DebugMessage(DEBUG_DETECT, "%s\n", sfip_ntoa(iph_ret_dst(p)));
1078 // #endif
1079 
1080             /* the packet matches this test, proceed to the next test */
1081             return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1082         }
1083     }
1084     else
1085     {
1086         /* global exception flag is up, we can't match on *any*
1087          * of the source addresses */
1088         DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"  global exception flag, \n"););
1089 
1090         if( sfvar_ip_in(rtn_idx->dip, GET_DST_IP(p)) ) return 0;
1091 
1092         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1093     }
1094 
1095     return 0;
1096 }
1097 
1098 
CheckSrcPortEqual(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)1099 int CheckSrcPortEqual(Packet *p, struct _RuleTreeNode *rtn_idx,
1100         RuleFpList *fp_list, int check_ports)
1101 {
1102     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcPortEqual: "););
1103 
1104 #ifdef TARGET_BASED
1105     /* Check if attributes provided match earlier */
1106     if (check_ports == 0)
1107     {
1108         DEBUG_WRAP(
1109             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortEq..."
1110                 "target-based-protocol=%d,ignoring ports\n",
1111                 GetProtocolReference(p)););
1112         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1113     }
1114     else
1115     {
1116         DEBUG_WRAP(
1117             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortEq..."
1118                 "target-based-protocol=%d,not ignoring ports\n",
1119                 GetProtocolReference(p)););
1120     }
1121 #endif /* TARGET_BASED */
1122     if( PortObjectHasPort(rtn_idx->src_portobject,p->sp) )
1123     {
1124         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "  SP match!\n"););
1125         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1126     }
1127     else
1128     {
1129         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "   SP mismatch!\n"););
1130     }
1131 
1132     return 0;
1133 }
1134 
CheckSrcPortNotEq(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)1135 int CheckSrcPortNotEq(Packet *p, struct _RuleTreeNode *rtn_idx,
1136         RuleFpList *fp_list, int check_ports)
1137 {
1138     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcPortNotEq: "););
1139 
1140 #ifdef TARGET_BASED
1141     /* Check if attributes provided match earlier */
1142     if (check_ports == 0)
1143     {
1144         DEBUG_WRAP(
1145             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortNotEq..."
1146                 "target-based-protocol=%d,ignoring ports\n",
1147                 GetProtocolReference(p)););
1148         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1149     }
1150     else
1151     {
1152         DEBUG_WRAP(
1153             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortNotEq..."
1154                 "target-based-protocol=%d,not ignoring ports\n",
1155                 GetProtocolReference(p)););
1156     }
1157 #endif /* TARGET_BASED */
1158     if( !PortObjectHasPort(rtn_idx->src_portobject,p->sp) )
1159     {
1160         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "  !SP match!\n"););
1161         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1162     }
1163     else
1164     {
1165         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "  !SP mismatch!\n"););
1166     }
1167 
1168     return 0;
1169 }
1170 
CheckDstPortEqual(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)1171 int CheckDstPortEqual(Packet *p, struct _RuleTreeNode *rtn_idx,
1172         RuleFpList *fp_list, int check_ports)
1173 {
1174     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckDstPortEqual: "););
1175 
1176 #ifdef TARGET_BASED
1177     /* Check if attributes provided match earlier */
1178     if (check_ports == 0)
1179     {
1180         DEBUG_WRAP(
1181             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortEq..."
1182             "target-based-protocol=%d,ignoring ports\n",
1183             GetProtocolReference(p)););
1184         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1185     }
1186     else
1187     {
1188         DEBUG_WRAP(
1189             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortEq..."
1190             "target-based-protocol=%d,not ignoring ports\n",
1191             GetProtocolReference(p)););
1192     }
1193 #endif /* TARGET_BASED */
1194     if( PortObjectHasPort(rtn_idx->dst_portobject,p->dp) )
1195     {
1196         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " DP match!\n"););
1197         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1198     }
1199     else
1200     {
1201         DEBUG_WRAP(DebugMessage(DEBUG_DETECT," DP mismatch!\n"););
1202     }
1203     return 0;
1204 }
1205 
1206 
CheckDstPortNotEq(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)1207 int CheckDstPortNotEq(Packet *p, struct _RuleTreeNode *rtn_idx,
1208         RuleFpList *fp_list, int check_ports)
1209 {
1210     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckDstPortNotEq: "););
1211 
1212 #ifdef TARGET_BASED
1213     /* Check if attributes provided match earlier */
1214     if (check_ports == 0)
1215     {
1216         DEBUG_WRAP(
1217             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortNotEq..."
1218             "target-based-protocol=%d,ignoring ports\n",
1219             GetProtocolReference(p)););
1220         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1221     }
1222     else
1223     {
1224         DEBUG_WRAP(
1225             DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortNotEq..."
1226             "target-based-protocol=%d,not ignoring ports\n",
1227             GetProtocolReference(p)););
1228     }
1229 #endif /* TARGET_BASED */
1230     if( !PortObjectHasPort(rtn_idx->dst_portobject,p->dp) )
1231     {
1232         DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " !DP match!\n"););
1233         return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports);
1234     }
1235     else
1236     {
1237         DEBUG_WRAP(DebugMessage(DEBUG_DETECT," !DP mismatch!\n"););
1238     }
1239 
1240     return 0;
1241 }
1242 
RuleListEnd(Packet * p,struct _RuleTreeNode * rtn_idx,RuleFpList * fp_list,int check_ports)1243 int RuleListEnd(Packet *p, struct _RuleTreeNode *rtn_idx,
1244         RuleFpList *fp_list, int check_ports)
1245 {
1246     return 1;
1247 }
1248 
1249 
OptListEnd(void * option_data,Packet * p)1250 int OptListEnd(void *option_data, Packet *p)
1251 {
1252     return DETECTION_OPTION_MATCH;
1253 }
1254 
1255 /* Rule Match Action Functions */
PassAction(void)1256 int PassAction(void)
1257 {
1258     pc.pass_pkts++;
1259 
1260     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"   => Pass rule, returning...\n"););
1261     return 1;
1262 }
1263 
AlertAction(Packet * p,OptTreeNode * otn,RuleTreeNode * rtn,Event * event)1264 int AlertAction(Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, Event * event)
1265 {
1266     if (!rtn)
1267     {
1268         // This function may be called from ppm, which doesn't do an RTN lookup
1269         rtn = getRuntimeRtnFromOtn(otn);
1270         if (!rtn)
1271             return 0;
1272     }
1273 
1274     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
1275                 "        <!!> Generating alert! \"%s\", policyId %d\n", otn->sigInfo.message, getIpsRuntimePolicy()););
1276 #if defined(FEAT_OPEN_APPID)
1277     updateEventAppName (p, otn, event);
1278 #endif /* defined(FEAT_OPEN_APPID) */
1279 
1280     /* Call OptTreeNode specific output functions */
1281     if(otn->outputFuncs)
1282         CallSigOutputFuncs(p, otn, event);
1283 
1284     if (ScAlertPacketCount())
1285         print_packet_count();
1286 
1287     CallAlertFuncs(p, otn->sigInfo.message, rtn->listhead, event);
1288 
1289     DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "   => Finishing alert packet!\n"););
1290 
1291     CallLogFuncs(p, otn->sigInfo.message, rtn->listhead, event);
1292 
1293     /*
1294     if(p->ssnptr != NULL && stream_api)
1295     {
1296         if(stream_api->alert_flush_stream(p) == 0)
1297         {
1298             CallLogFuncs(p, otn->sigInfo.message, otn->rtn->listhead, event);
1299         }
1300     }
1301     else
1302     {
1303         CallLogFuncs(p, otn->sigInfo.message, otn->rtn->listhead, event);
1304     }
1305     */
1306 
1307     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"   => Alert packet finished, returning!\n"););
1308 
1309     return 1;
1310 }
1311 
DropAction(Packet * p,OptTreeNode * otn,RuleTreeNode * rtn,Event * event)1312 int DropAction(Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, Event * event)
1313 {
1314     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
1315                "        <!!> Generating Alert and dropping! \"%s\"\n",
1316                otn->sigInfo.message););
1317 
1318     if(stream_api && !stream_api->alert_inline_midstream_drops())
1319     {
1320         if(session_api->get_session_flags(p->ssnptr) & SSNFLAG_MIDSTREAM)
1321         {
1322             DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
1323                 " <!!> Alert Came From Midstream Session Silently Drop! "
1324                 "\"%s\"\n", otn->sigInfo.message););
1325 
1326             Active_DropSession(p);
1327             if (pkt_trace_enabled)
1328                 addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE,
1329                     "Snort: gid %u, sid %u, midstream %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg()));
1330             else addPktTraceData(VERDICT_REASON_SNORT, 0);
1331             return 1;
1332         }
1333     }
1334 
1335     /*
1336     **  Set packet flag so output plugins will know we dropped the
1337     **  packet we just logged.
1338     */
1339     Active_DropSession(p);
1340 #if defined(FEAT_OPEN_APPID)
1341     updateEventAppName (p, otn, event);
1342 #endif /* defined(FEAT_OPEN_APPID) */
1343 
1344     CallAlertFuncs(p, otn->sigInfo.message, rtn->listhead, event);
1345 
1346     CallLogFuncs(p, otn->sigInfo.message, rtn->listhead, event);
1347 
1348     if (pkt_trace_enabled)
1349         addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE,
1350             "Snort detect_drop: gid %u, sid %u, %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg()));
1351     else addPktTraceData(VERDICT_REASON_SNORT, 0);
1352     return 1;
1353 }
1354 
SDropAction(Packet * p,OptTreeNode * otn,Event * event)1355 int SDropAction(Packet * p, OptTreeNode * otn, Event * event)
1356 {
1357     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,
1358                "        <!!> Dropping without Alerting! \"%s\"\n",
1359                otn->sigInfo.message););
1360 
1361     // Let's silently drop the packet
1362     Active_DropSession(p);
1363     if (pkt_trace_enabled)
1364         addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE,
1365             "Snort detect_sdrop: gid %u, sid %u, %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg()));
1366     else addPktTraceData(VERDICT_REASON_SNORT, 0);
1367     return 1;
1368 }
1369 
LogAction(Packet * p,OptTreeNode * otn,RuleTreeNode * rtn,Event * event)1370 int LogAction(Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, Event * event)
1371 {
1372     DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"   => Logging packet data and returning...\n"););
1373 
1374     CallLogFuncs(p, otn->sigInfo.message, rtn->listhead, event);
1375 
1376 #ifdef BENCHMARK
1377     printf("        <!!> Check count = %d\n", check_count);
1378     check_count = 0;
1379     printf(" **** cmpcount: %d **** \n", cmpcount);
1380 #endif
1381 
1382     return 1;
1383 }
1384 
1385 /* end of rule action functions */
1386 
1387