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