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