1 /* $Id$ */
2 /****************************************************************************
3  *
4  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
5  * Copyright (C) 2005-2013 Sourcefire, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License Version 2 as
9  * published by the Free Software Foundation.  You may not use, modify or
10  * distribute this program under any other version of the GNU General
11  * Public License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  *
22  ****************************************************************************/
23 
24 // @file    active.h
25 // @author  Russ Combs <rcombs@sourcefire.com>
26 
27 #ifndef __ACTIVE_H__
28 #define __ACTIVE_H__
29 
30 #include "decode.h"
31 #include "snort.h"
32 
33 #ifdef ACTIVE_RESPONSE
34 #include "encode.h"
35 
36 int Active_Init(SnortConfig*);
37 int Active_Term(void);
38 
39 typedef void (*Active_ResponseFunc)(Packet*, void* data);
40 
41 int Active_QueueReject(void);
42 int Active_QueueResponse(Active_ResponseFunc, void*);
43 int Active_ResetQueue(void);
44 
45 // this must be called on the wire packet and not a
46 // reassembled packet so that encoding is correct.
47 int Active_SendResponses(Packet*);
48 uint64_t Active_GetInjects(void);
49 
50 // NULL flags implies ENC_FLAG_FWD
51 void Active_KillSession(Packet*, EncodeFlags*);
52 
53 void Active_SendReset(Packet*, EncodeFlags);
54 void Active_SendUnreach(Packet*, EncodeType);
55 bool Active_SendData(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len);
56 void Active_InjectData(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len);
57 void Active_UDPInjectData(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len);
58 
59 int Active_IsRSTCandidate(const Packet*);
60 int Active_IsUNRCandidate(const Packet*);
61 
62 int Active_IsEnabled(void);
63 void Active_SetEnabled(int on_off);
64 
65 #endif // ACTIVE_RESPONSE
66 
67 typedef enum {
68     ACTIVE_ALLOW,       // don't drop
69     ACTIVE_CANT_DROP,   // can't drop
70     ACTIVE_WOULD_DROP,  // would drop
71     ACTIVE_DROP,        // should drop
72     ACTIVE_FORCE_DROP,  // must drop
73     ACTIVE_RETRY        // queue for retry
74 } tActiveDrop;
75 
76 typedef enum {
77     ACTIVE_SSN_ALLOW,       // don't drop
78     ACTIVE_SSN_DROP,        // can drop and reset
79     ACTIVE_SSN_DROP_WITHOUT_RESET  // can drop but without reset
80 } tActiveSsnDrop;
81 
82 extern tActiveDrop active_drop_pkt;
83 extern tActiveSsnDrop active_drop_ssn;
84 #ifdef ACTIVE_RESPONSE
85 extern int active_have_rsp;
86 #endif
87 extern int active_tunnel_bypass;
88 extern int active_suspend;
89 
Active_Reset(void)90 static inline void Active_Reset (void)
91 {
92     active_drop_pkt = ACTIVE_ALLOW;
93     active_drop_ssn = ACTIVE_SSN_ALLOW;
94 #ifdef ACTIVE_RESPONSE
95     active_have_rsp = 0;
96 #endif
97     active_tunnel_bypass = 0;
98 }
99 
Active_Suspend(void)100 static inline void Active_Suspend (void)
101 {
102     active_suspend = 1;
103 }
104 
Active_Resume(void)105 static inline void Active_Resume (void)
106 {
107     active_suspend = 0;
108 }
109 
Active_Suspended(void)110 static inline bool Active_Suspended (void)
111 {
112     return ( active_suspend != 0 );
113 }
114 
Active_GetDisposition(void)115 static inline tActiveDrop Active_GetDisposition (void)
116 {
117     return active_drop_pkt;
118 }
119 
Active_CantDrop(void)120 static inline void Active_CantDrop(void)
121 {
122 #if 0
123     // not yet supported
124     if ( active_drop_pkt < ACTIVE_CANT_DROP )
125         active_drop_pkt = ACTIVE_CANT_DROP;
126 #else
127     if ( active_drop_pkt < ACTIVE_WOULD_DROP )
128         active_drop_pkt = ACTIVE_WOULD_DROP;
129 #endif
130 }
131 
Active_ForceDropPacket(void)132 static inline void Active_ForceDropPacket( void )
133 {
134     if ( Active_Suspended() )
135         Active_CantDrop();
136     else
137         active_drop_pkt = ACTIVE_FORCE_DROP;
138 }
139 
Active_NapDropPacket(const Packet * p)140 static inline void Active_NapDropPacket( const Packet* p )
141 {
142     if ( Active_Suspended() )
143     {
144         Active_CantDrop();
145     }
146     else if ( active_drop_pkt != ACTIVE_FORCE_DROP )
147     {
148         if ( ScNapInlineMode() )
149         {
150             if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )
151                 active_drop_pkt = ACTIVE_DROP;
152             else
153                 active_drop_pkt = ACTIVE_WOULD_DROP;
154         }
155         else if (ScNapInlineTestMode())
156         {
157             active_drop_pkt = ACTIVE_WOULD_DROP;
158         }
159     }
160 }
161 
Active_DropPacket(const Packet * p)162 static inline void Active_DropPacket( const Packet* p )
163 {
164     if ( Active_Suspended() )
165     {
166         Active_CantDrop();
167     }
168     else if ( active_drop_pkt != ACTIVE_FORCE_DROP )
169     {
170         if ( ScIpsInlineMode() )
171         {
172             if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )
173                 active_drop_pkt = ACTIVE_DROP;
174             else
175                 active_drop_pkt = ACTIVE_WOULD_DROP;
176         }
177         else if (ScIpsInlineTestMode())
178         {
179             active_drop_pkt = ACTIVE_WOULD_DROP;
180         }
181     }
182 }
183 
Active_DAQRetryPacket(const Packet * p)184 static inline bool Active_DAQRetryPacket( const Packet *p )
185 {
186     bool retry_queued = false;
187 
188     if( ( active_drop_pkt == ACTIVE_ALLOW ) && DAQ_CanRetry( ) )
189     {
190         if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )
191         {
192             active_drop_pkt = ACTIVE_RETRY;
193             retry_queued = true;
194         }
195     }
196 
197     return retry_queued;
198 }
199 
Active_DAQDropPacket(const Packet * p)200 static inline void Active_DAQDropPacket(const Packet *p)
201 {
202     if ( Active_Suspended() )
203     {
204         Active_CantDrop();
205     }
206     else if ( active_drop_pkt != ACTIVE_FORCE_DROP )
207     {
208         if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )
209             active_drop_pkt = ACTIVE_DROP;
210         else
211             active_drop_pkt = ACTIVE_WOULD_DROP;
212     }
213 }
214 
_Active_DropSession(const Packet * p,tActiveSsnDrop ssn_drop)215 static inline void _Active_DropSession (const Packet* p, tActiveSsnDrop ssn_drop)
216 {
217     if ( Active_Suspended() )
218     {
219         Active_CantDrop();
220         return;
221     }
222     active_drop_ssn = ssn_drop;
223     Active_DropPacket(p);
224 }
225 
_Active_ForceDropSession(tActiveSsnDrop ssn_drop)226 static inline void _Active_ForceDropSession (tActiveSsnDrop ssn_drop)
227 {
228     if ( Active_Suspended() )
229     {
230         Active_CantDrop();
231         return;
232     }
233     active_drop_ssn = ssn_drop;
234     Active_ForceDropPacket();
235 }
236 
Active_DropSession(const Packet * p)237 static inline void Active_DropSession (const Packet* p)
238 {
239     _Active_DropSession(p, ACTIVE_SSN_DROP);
240 }
241 
Active_ForceDropSession(void)242 static inline void Active_ForceDropSession (void)
243 {
244     _Active_ForceDropSession(ACTIVE_SSN_DROP);
245 }
246 
Active_DropSessionWithoutReset(const Packet * p)247 static inline void Active_DropSessionWithoutReset (const Packet* p)
248 {
249     _Active_DropSession(p, ACTIVE_SSN_DROP_WITHOUT_RESET);
250 }
251 
Active_ForceDropSessionWithoutReset(void)252 static inline void Active_ForceDropSessionWithoutReset (void)
253 {
254     _Active_ForceDropSession(ACTIVE_SSN_DROP_WITHOUT_RESET);
255 }
256 
Active_PacketWouldBeDropped(void)257 static inline int Active_PacketWouldBeDropped (void)
258 {
259     return (active_drop_pkt == ACTIVE_WOULD_DROP );
260 }
261 
Active_PacketForceDropped(void)262 static inline int Active_PacketForceDropped (void)
263 {
264     return (active_drop_pkt == ACTIVE_FORCE_DROP );
265 }
266 
Active_PacketWasDropped(void)267 static inline int Active_PacketWasDropped (void)
268 {
269     return ( active_drop_pkt >= ACTIVE_DROP );
270 }
271 
Active_RetryIsPending(void)272 static inline int Active_RetryIsPending (void)
273 {
274     return ( active_drop_pkt == ACTIVE_RETRY );
275 }
276 
Active_SessionWasDropped(void)277 static inline int Active_SessionWasDropped (void)
278 {
279     return ( active_drop_ssn != ACTIVE_SSN_ALLOW );
280 }
281 
282 #ifdef ACTIVE_RESPONSE
Active_ResponseQueued(void)283 static inline int Active_ResponseQueued (void)
284 {
285     return ( active_have_rsp != ACTIVE_SSN_ALLOW );
286 }
287 #endif
288 
Active_SetTunnelBypass(void)289 static inline void Active_SetTunnelBypass (void)
290 {
291     active_tunnel_bypass++;
292 }
293 
Active_ClearTunnelBypass(void)294 static inline void Active_ClearTunnelBypass (void)
295 {
296     active_tunnel_bypass--;
297 }
298 
Active_GetTunnelBypass(void)299 static inline int Active_GetTunnelBypass (void)
300 {
301     return ( active_tunnel_bypass > 0 );
302 }
303 
304 // drops current session with active response invoked
305 // for rules with action = drop | sdrop | reject
306 int Active_DropAction(Packet*);
307 
308 // drops current session w/o active response invoked
309 // for rules with custom response = resp3 | react
310 int Active_IgnoreSession(Packet*);
311 
312 // force drops the current session w/o active response invoked
313 // ignores policy/inline test mode and treat drop as alert
314 int Active_ForceDropAction(Packet *p);
315 
316 // force drops the current session with active response invoked
317 // ignores policy/inline test mode and treat drop as alert
318 int Active_ForceDropResetAction(Packet *p);
319 
320 const char* Active_GetDispositionString();
321 
322 #endif // __ACTIVE_H__
323 
324