1 /* $Id$ */
2 /*
3 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4 ** Copyright (C) 2010-2013 Sourcefire, Inc.
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License Version 2 as
8 ** published by the Free Software Foundation. You may not use, modify or
9 ** distribute this program under any other version of the GNU General
10 ** Public License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 #ifdef NORMALIZER
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "active.h"
28 #include "mstring.h"
29 #include "normalize.h"
30 #include "parser.h"
31 #include "plugbase.h"
32 #include "profiler.h"
33 #include "sf_types.h"
34 #include "sfPolicy.h"
35 #include "snort.h"
36 #include "spp_normalize.h"
37 #include "snort_stream_tcp.h"
38
39 // Priority for Normalize preproc
40 #define PP_NORMALIZE_PRIORITY PRIORITY_CORE + PP_CORE_ORDER_NORML
41
42 static tSfPolicyUserContextId base_set = NULL;
43
44 #ifdef PERF_PROFILING
45 PreprocStats norm_perf_stats;
46 #endif
47
48 static void Preproc_Execute(Packet* , void*);
49 static void Preproc_CleanExit(int, void*);
50 static void Preproc_Reset(int, void*);
51 static void Preproc_PostConfigInit(struct _SnortConfig *, void*);
52 static int Preproc_CheckConfig (struct _SnortConfig *);
53 static void Preproc_ResetStats(int, void*);
54 static void Preproc_PrintStats(int);
55 static void Preproc_Install(struct _SnortConfig *);
56
57 static void Init_IP4(struct _SnortConfig *, char*);
58 static void Init_ICMP4(struct _SnortConfig *, char*);
59 static void Init_IP6(struct _SnortConfig *, char*);
60 static void Init_ICMP6(struct _SnortConfig *, char*);
61 static void Init_TCP(struct _SnortConfig *, char*);
62
63 static void Parse_IP4(struct _SnortConfig *, NormalizerContext*, char*);
64 static void Parse_ICMP4(NormalizerContext*, char*);
65 static void Parse_IP6(struct _SnortConfig *, NormalizerContext*, char*);
66 static void Parse_ICMP6(NormalizerContext*, char*);
67 static void Parse_TCP(NormalizerContext*, char*);
68
69 static void Print_IP4(struct _SnortConfig *, const NormalizerContext*);
70 static void Print_ICMP4(const NormalizerContext*);
71 static void Print_IP6(struct _SnortConfig *, const NormalizerContext*);
72 static void Print_ICMP6(const NormalizerContext*);
73 static void Print_TCP(const NormalizerContext*);
74
75 #ifdef SNORT_RELOAD
76 static void Reload_IP4(struct _SnortConfig *, char*, void **);
77 static void Reload_ICMP4(struct _SnortConfig *, char*, void **);
78 static void Reload_IP6(struct _SnortConfig *, char*, void **);
79 static void Reload_ICMP6(struct _SnortConfig *, char*, void **);
80 static void Reload_TCP(struct _SnortConfig *, char*, void **);
81
82 static int Reload_Verify(struct _SnortConfig *, void *);
83 static void* Reload_Swap(struct _SnortConfig *, void *);
84 static void Reload_Free(void*);
85 #endif
86
87 #ifdef SNORT_RELOAD
88 #define NORM_FUNCS(p) Init_ ## p, Reload_ ## p, Reload_Verify, Reload_Swap, Reload_Free
89 #else
90 #define NORM_FUNCS(p) Init_ ## p
91 #endif
92
SetupNormalizer(void)93 void SetupNormalizer (void)
94 {
95 RegisterPreprocessor("normalize_ip4", NORM_FUNCS(IP4));
96 RegisterPreprocessor("normalize_icmp4", NORM_FUNCS(ICMP4));
97 RegisterPreprocessor("normalize_ip6", NORM_FUNCS(IP6));
98 RegisterPreprocessor("normalize_icmp6", NORM_FUNCS(ICMP6));
99 RegisterPreprocessor("normalize_tcp", NORM_FUNCS(TCP));
100 }
101
102 //-------------------------------------------------------------------------
103 // basic initialization stuff
104 //-------------------------------------------------------------------------
105
106 #define PROTO_BITS (PROTO_BIT__IP|PROTO_BIT__ICMP|PROTO_BIT__TCP)
107
Init_GetContext(struct _SnortConfig * sc)108 static NormalizerContext* Init_GetContext (struct _SnortConfig *sc)
109 {
110 NormalizerContext* pc = NULL;
111 tSfPolicyId policy_id = getParserPolicy(sc);
112
113 if ( ScNapPassiveModeNewConf(sc) )
114 return NULL;
115
116 if ( !base_set )
117 {
118 base_set = sfPolicyConfigCreate();
119 Preproc_Install(sc);
120 }
121
122 sc->normalizer_set = true;
123
124 sfPolicyUserPolicySet(base_set, policy_id);
125 pc = sfPolicyUserDataGetCurrent(base_set);
126
127 if ( !pc )
128 {
129 pc = (NormalizerContext* )SnortAlloc(sizeof(NormalizerContext));
130 sfPolicyUserDataSetCurrent(base_set, pc);
131 if( pc->regFunc != reload)
132 {
133 AddFuncToPreprocList( sc, Preproc_Execute, PP_NORMALIZE_PRIORITY, PP_NORMALIZE, PROTO_BITS);
134 pc->regFunc = init;
135 }
136 session_api->enable_preproc_all_ports( sc, PP_NORMALIZE, PROTO_BITS );
137 }
138 pc->normMode = ScNapInlineTestModeNewConf(sc) ? NORM_MODE_WOULDA : NORM_MODE_ON;
139
140 return pc;
141 }
142
143 #define NOT_INLINE "WARNING: %s normalizations disabled because not inline.\n"
144
Init_IP4(struct _SnortConfig * sc,char * args)145 static void Init_IP4 (struct _SnortConfig *sc, char* args)
146 {
147 NormalizerContext* pc = Init_GetContext(sc);
148
149 if ( pc )
150 Parse_IP4(sc, pc, args);
151 else
152 LogMessage(NOT_INLINE, "ip4");
153 }
154
Init_ICMP4(struct _SnortConfig * sc,char * args)155 static void Init_ICMP4 (struct _SnortConfig *sc, char* args)
156 {
157 NormalizerContext* pc = Init_GetContext(sc);
158
159 if ( pc )
160 Parse_ICMP4(pc, args);
161 else
162 LogMessage(NOT_INLINE, "icmp4");
163 }
164
Init_IP6(struct _SnortConfig * sc,char * args)165 static void Init_IP6 (struct _SnortConfig *sc, char* args)
166 {
167 NormalizerContext* pc = Init_GetContext(sc);
168
169 if ( pc )
170 Parse_IP6(sc, pc, args);
171 else
172 LogMessage(NOT_INLINE, "ip6");
173 }
174
Init_ICMP6(struct _SnortConfig * sc,char * args)175 static void Init_ICMP6 (struct _SnortConfig *sc, char* args)
176 {
177 NormalizerContext* pc = Init_GetContext(sc);
178
179 if ( pc )
180 Parse_ICMP6(pc, args);
181 else
182 LogMessage(NOT_INLINE, "icmp6");
183 }
184
Init_TCP(struct _SnortConfig * sc,char * args)185 static void Init_TCP (struct _SnortConfig *sc, char* args)
186 {
187 NormalizerContext* pc = Init_GetContext(sc);
188
189 if ( pc )
190 Parse_TCP(pc, args);
191 else
192 LogMessage(NOT_INLINE, "tcp");
193 }
194
195 //-------------------------------------------------------------------------
196 // parsing stuff
197 //-------------------------------------------------------------------------
198
199 // options may appear in any order separated by ',':
200 // preprocessor normalize_ip4: [id] [df] [rf] [tos] [trim]
Parse_IP4(struct _SnortConfig * sc,NormalizerContext * pc,char * args)201 static void Parse_IP4 (struct _SnortConfig *sc, NormalizerContext* pc, char* args)
202 {
203 char** toks;
204 int num_toks;
205 int i;
206
207 Norm_Enable(pc, NORM_IP4);
208
209 if ( !args )
210 args = "";
211
212 toks = mSplit(args, ", ", 0, &num_toks, 0);
213
214 for (i = 0; i < num_toks; i++)
215 {
216 #if 0
217 if ( !strcasecmp(toks[i], "id") )
218 {
219 Norm_Enable(pc, NORM_IP4_ID);
220 }
221 else
222 #endif
223 if ( !strcasecmp(toks[i], "df") )
224 {
225 Norm_Enable(pc, NORM_IP4_DF);
226 }
227 else if ( !strcasecmp(toks[i], "rf") )
228 {
229 Norm_Enable(pc, NORM_IP4_RF);
230 }
231 else if ( !strcasecmp(toks[i], "tos") )
232 {
233 Norm_Enable(pc, NORM_IP4_TOS);
234 }
235 else if ( !strcasecmp(toks[i], "trim") )
236 {
237 Norm_Enable(pc, NORM_IP4_TRIM);
238 }
239 else
240 {
241 ParseError("Invalid preprocessor normalize_ip4 option '%s'", toks[i]);
242 }
243 }
244 {
245 tSfPolicyId pid = getParserPolicy(sc);
246 SnortPolicy* policy = sc->targeted_policies[pid];
247
248 if ( (policy->new_ttl > 1) && (policy->new_ttl >= policy->min_ttl) )
249 {
250 Norm_Enable(pc, NORM_IP4_TTL);
251 }
252 }
253 mSplitFree(&toks, num_toks);
254 Print_IP4(sc, pc);
255 }
256
257 // preprocessor normalize_icmp4
Parse_ICMP4(NormalizerContext * pc,char * args)258 static void Parse_ICMP4 (NormalizerContext* pc, char* args)
259 {
260 Norm_Enable(pc, NORM_ICMP4);
261 Print_ICMP4(pc);
262 }
263
264 // preprocessor normalize_ip6
Parse_IP6(struct _SnortConfig * sc,NormalizerContext * pc,char * args)265 static void Parse_IP6 (struct _SnortConfig *sc, NormalizerContext* pc, char* args)
266 {
267 Norm_Enable(pc, NORM_IP6);
268 {
269 tSfPolicyId pid = getParserPolicy(sc);
270 SnortPolicy* policy = sc->targeted_policies[pid];
271
272 if ( (policy->new_ttl > 1) && (policy->new_ttl >= policy->min_ttl) )
273 {
274 Norm_Enable(pc, NORM_IP6_TTL);
275 }
276 }
277 Print_IP6(sc, pc);
278 }
279
280 // preprocessor normalize_icmp6
Parse_ICMP6(NormalizerContext * pc,char * args)281 static void Parse_ICMP6 (NormalizerContext* pc, char* args)
282 {
283 Norm_Enable(pc, NORM_ICMP6);
284 Print_ICMP6(pc);
285 }
286
287 // options may appear in any order separated by ',':
288 // preprocessor normalize_tcp: [ecn packet|stream] [urp] [opts] [allow <opt>+]
289 //
290 // <opt> ::= sack|echo|partial_order|alt_checksum|md5|#
291 // where 2 <= # <= 255.
Parse_TCP(NormalizerContext * pc,char * args)292 static void Parse_TCP (NormalizerContext* pc, char* args)
293 {
294 char **toks;
295 int num_toks;
296 int i, state = 0, opts = 0;
297
298 if ( !args ) args = "";
299 toks = mSplit(args, ", ", 0, &num_toks, 0);
300
301 for (i = 0; i < num_toks; i++)
302 {
303 switch ( state ) {
304 case 0:
305 if ( !strcasecmp(toks[i], "ecn") )
306 {
307 state = 1;
308 }
309 else if ( !strcasecmp(toks[i], "block") )
310 {
311 Norm_Enable(pc, NORM_TCP_BLOCK);
312 }
313 else if ( !strcasecmp(toks[i], "rsv") )
314 {
315 Norm_Enable(pc, NORM_TCP_RSV);
316 }
317 else if ( !strcasecmp(toks[i], "pad") )
318 {
319 Norm_Enable(pc, NORM_TCP_PAD);
320 }
321 else if ( !strcasecmp(toks[i], "req_urg") )
322 {
323 Norm_Enable(pc, NORM_TCP_REQ_URG);
324 }
325 else if ( !strcasecmp(toks[i], "req_pay") )
326 {
327 Norm_Enable(pc, NORM_TCP_REQ_PAY);
328 }
329 else if ( !strcasecmp(toks[i], "req_urp") )
330 {
331 Norm_Enable(pc, NORM_TCP_URP);
332 }
333 else if ( !strcasecmp(toks[i], "urp") )
334 {
335 Norm_Enable(pc, NORM_TCP_URP);
336 }
337 else if ( !strcasecmp(toks[i], "opts") )
338 {
339 Norm_Enable(pc, NORM_TCP_OPT);
340 }
341 else if ( !strcasecmp(toks[i], "allow") )
342 {
343 state = 2;
344 opts = 0;
345 }
346 else if ( !strcasecmp(toks[i], "ips") )
347 {
348 Norm_Enable(pc, NORM_TCP_IPS);
349 }
350 else if ( !strcasecmp(toks[i], "trim_syn") )
351 {
352 Norm_Enable(pc, NORM_TCP_TRIM_SYN);
353 }
354 else if ( !strcasecmp(toks[i], "trim_rst") )
355 {
356 Norm_Enable(pc, NORM_TCP_TRIM_RST);
357 }
358 else if ( !strcasecmp(toks[i], "trim_win") )
359 {
360 Norm_Enable(pc, NORM_TCP_TRIM_WIN);
361 }
362 else if ( !strcasecmp(toks[i], "trim_mss") )
363 {
364 Norm_Enable(pc, NORM_TCP_TRIM_MSS);
365 }
366 else if ( !strcasecmp(toks[i], "trim") )
367 {
368 //Catch-all / backwards compatible
369 Norm_Enable(pc, NORM_TCP_TRIM_SYN);
370 Norm_Enable(pc, NORM_TCP_TRIM_RST);
371 Norm_Enable(pc, NORM_TCP_TRIM_WIN);
372 Norm_Enable(pc, NORM_TCP_TRIM_MSS);
373 }
374 else
375 {
376 ParseError("Invalid preprocessor normalize_tcp option '%s'", toks[i]);
377 }
378 break;
379
380 case 1:
381 if ( !strcasecmp(toks[i], "stream") )
382 {
383 Norm_Enable(pc, NORM_TCP_ECN_STR);
384 state = 0;
385 }
386 else if ( !strcasecmp(toks[i], "packet") )
387 {
388 Norm_Enable(pc, NORM_TCP_ECN_PKT);
389 state = 0;
390 }
391 else
392 {
393 ParseError("Unknown ecn argument '%s'"
394 " Need packet|stream", toks[i]);
395 }
396 break;
397
398 case 2:
399 if ( !strcasecmp(toks[i], "sack") )
400 {
401 Norm_TcpPassOption(pc, 4);
402 Norm_TcpPassOption(pc, 5);
403 opts++;
404 }
405 else if ( !strcasecmp(toks[i], "echo") )
406 {
407 Norm_TcpPassOption(pc, 6);
408 Norm_TcpPassOption(pc, 7);
409 opts++;
410 }
411 else if ( !strcasecmp(toks[i], "partial_order") )
412 {
413 Norm_TcpPassOption(pc, 9);
414 Norm_TcpPassOption(pc, 10);
415 opts++;
416 }
417 else if ( !strcasecmp(toks[i], "conn_count") )
418 {
419 Norm_TcpPassOption(pc, 11);
420 Norm_TcpPassOption(pc, 12);
421 Norm_TcpPassOption(pc, 13);
422 opts++;
423 }
424 else if ( !strcasecmp(toks[i], "alt_checksum") )
425 {
426 Norm_TcpPassOption(pc, 14);
427 Norm_TcpPassOption(pc, 15);
428 opts++;
429 }
430 else if ( !strcasecmp(toks[i], "md5") )
431 {
432 Norm_TcpPassOption(pc, 19);
433 opts++;
434 }
435 else if ( isdigit(*toks[i]) )
436 {
437 int opt = atoi(toks[i]);
438 if ( 1 < opt && opt < 256 )
439 {
440 Norm_TcpPassOption(pc, (uint8_t)opt);
441 opts++;
442 }
443 else
444 {
445 ParseError("Bad TCP option number '%s'; must be"
446 " between 2 and 255 inclusive", toks[i]);
447 }
448 }
449 else if ( opts > 0 )
450 {
451 i--;
452 state = 0;
453 }
454 else
455 {
456 ParseError("Bad TCP option '%s'; must be"
457 " sack|echo|partial_order|conn_count|alt_checksum|md5|#", toks[i]);
458 }
459 break;
460 }
461 }
462 if ( state == 1 )
463 {
464 ParseError("Missing argument for '%s'", toks[i-1]);
465 }
466 mSplitFree(&toks, num_toks);
467 Print_TCP(pc);
468 }
469
470 //-------------------------------------------------------------------------
471 // printing stuff
472 //-------------------------------------------------------------------------
473
474 #define ON "on"
475 #define OFF "off"
476
LogConf(const char * p,const char * s)477 static inline void LogConf (const char* p, const char* s)
478 {
479 LogMessage("%12s: %s\n", p, s);
480 }
481
LogFlag(const char * p,const NormalizerContext * nc,NormFlags nf)482 static inline void LogFlag (
483 const char* p, const NormalizerContext* nc, NormFlags nf)
484 {
485 const char* s = Norm_IsEnabled(nc, nf) ? ON : OFF;
486 LogConf(p, s);
487 }
488
Print_IP4(struct _SnortConfig * sc,const NormalizerContext * nc)489 static void Print_IP4 (struct _SnortConfig *sc, const NormalizerContext* nc)
490 {
491 LogMessage("Normalizer config:\n");
492 LogFlag("ip4", nc, NORM_IP4);
493
494 if ( Norm_IsEnabled(nc, NORM_IP4) )
495 {
496 //LogFlag("ip4::id", nc, NORM_IP4_ID);
497 LogFlag("ip4::df", nc, NORM_IP4_DF);
498 LogFlag("ip4::rf", nc, NORM_IP4_RF);
499 LogFlag("ip4::tos", nc, NORM_IP4_TOS);
500 LogFlag("ip4::trim", nc, NORM_IP4_TRIM);
501
502 if ( Norm_IsEnabled(nc, NORM_IP4_TTL) )
503 {
504 tSfPolicyId pid = getParserPolicy(sc);
505 int min = sc->targeted_policies[pid]->min_ttl;
506 int new = sc->targeted_policies[pid]->new_ttl;
507 LogMessage("%12s: %s (min=%d, new=%d)\n", "ip4::ttl", ON, min, new);
508 }
509 else
510 LogConf("ip4::ttl", OFF);
511 }
512 }
513
Print_ICMP4(const NormalizerContext * nc)514 static void Print_ICMP4 (const NormalizerContext* nc)
515 {
516 LogMessage("Normalizer config:\n");
517 LogFlag("icmp4", nc, NORM_ICMP4);
518 }
519
Print_IP6(struct _SnortConfig * sc,const NormalizerContext * nc)520 static void Print_IP6 (struct _SnortConfig *sc, const NormalizerContext* nc)
521 {
522 LogMessage("Normalizer config:\n");
523 LogFlag("ip6", nc, NORM_IP6);
524
525 if ( Norm_IsEnabled(nc, NORM_IP6) )
526 {
527 if ( Norm_IsEnabled(nc, NORM_IP6_TTL) )
528 {
529 tSfPolicyId pid = getParserPolicy(sc);
530 int min = sc->targeted_policies[pid]->min_ttl;
531 int new = sc->targeted_policies[pid]->new_ttl;
532 LogMessage("%12s: %s (min=%d, new=%d)\n", "ip6::hops", ON, min, new);
533 }
534 else
535 LogConf("ip6::hops", OFF);
536 }
537 }
538
Print_ICMP6(const NormalizerContext * nc)539 static void Print_ICMP6 (const NormalizerContext* nc)
540 {
541 LogMessage("Normalizer config:\n");
542 LogFlag("icmp6", nc, NORM_ICMP6);
543 }
544
Print_TCP(const NormalizerContext * nc)545 static void Print_TCP (const NormalizerContext* nc)
546 {
547 LogMessage("Normalizer config:\n");
548 LogFlag("tcp", nc, NORM_TCP);
549
550 if ( Norm_IsEnabled(nc, NORM_TCP) )
551 {
552 const char* s;
553
554 if ( Norm_IsEnabled(nc, NORM_TCP_ECN_PKT) )
555 s = "packet";
556 else if ( Norm_IsEnabled(nc, NORM_TCP_ECN_STR) )
557 s = "stream";
558 else
559 s = OFF;
560
561 LogConf("tcp::ecn", s);
562 LogFlag("tcp::block", nc, NORM_TCP_BLOCK);
563 LogFlag("tcp::rsv", nc, NORM_TCP_RSV);
564 LogFlag("tcp::pad", nc, NORM_TCP_PAD);
565 LogFlag("tcp::req_urg", nc, NORM_TCP_REQ_URG);
566 LogFlag("tcp::req_pay", nc, NORM_TCP_REQ_PAY);
567 LogFlag("tcp::req_urp", nc, NORM_TCP_REQ_URP);
568 LogFlag("tcp::urp", nc, NORM_TCP_URP);
569
570 if ( Norm_IsEnabled(nc, NORM_TCP_OPT) )
571 {
572 char buf[1024] = "";
573 char* p = buf;
574 int opt;
575 size_t min;
576
577 p += snprintf(p, buf+sizeof(buf)-p, "%s", "(allow ");
578 min = strlen(buf);
579
580 // TBD translate options to keywords allowed by parser
581 for ( opt = 2; opt < 256; opt++ )
582 {
583 const char* fmt = (strlen(buf) > min) ? ",%d" : "%d";
584 if ( Norm_TcpIsOptional(nc, opt) )
585 p += snprintf(p, buf+sizeof(buf)-p, fmt, opt);
586 }
587 if ( strlen(buf) > min )
588 {
589 snprintf(p, buf+sizeof(buf)-p, "%c", ')');
590 buf[sizeof(buf)-1] = '\0';
591 }
592 LogMessage("%12s: %s %s\n", "tcp::opt", ON, buf);
593 }
594 else
595 LogConf("tcp::opt", OFF);
596
597 LogFlag("tcp::ips", nc, NORM_TCP_IPS);
598 LogFlag("tcp::trim_syn", nc, NORM_TCP_TRIM_SYN);
599 LogFlag("tcp::trim_rst", nc, NORM_TCP_TRIM_RST);
600 LogFlag("tcp::trim_win", nc, NORM_TCP_TRIM_WIN);
601 LogFlag("tcp::trim_mss", nc, NORM_TCP_TRIM_MSS);
602 }
603 }
604
605 //-------------------------------------------------------------------------
606 // preproc (main) stuff
607 //-------------------------------------------------------------------------
608
Preproc_Install(struct _SnortConfig * sc)609 static void Preproc_Install (struct _SnortConfig *sc)
610 {
611 #ifdef PERF_PROFILING
612 RegisterPreprocessorProfile(
613 "normalize", &norm_perf_stats, 0, &totalPerfStats, NULL);
614 #endif
615 AddFuncToPreprocCleanExitList(
616 Preproc_CleanExit, NULL, PRIORITY_LAST, PP_NORMALIZE);
617
618 AddFuncToPreprocResetList(
619 Preproc_Reset, NULL, PP_NORMALIZE_PRIORITY, PP_NORMALIZE);
620
621 AddFuncToPreprocResetStatsList(
622 Preproc_ResetStats, NULL, PP_NORMALIZE_PRIORITY, PP_NORMALIZE);
623
624 AddFuncToConfigCheckList(sc, Preproc_CheckConfig);
625 AddFuncToPreprocPostConfigList(sc, Preproc_PostConfigInit, NULL);
626 RegisterPreprocStats("normalize", Preproc_PrintStats);
627 }
628
629 //-------------------------------------------------------------------------
630
Preproc_CheckPolicy(struct _SnortConfig * sc,tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)631 static int Preproc_CheckPolicy (
632 struct _SnortConfig *sc,
633 tSfPolicyUserContextId set,
634 tSfPolicyId pid,
635 void* pv)
636 {
637 //NormalizerContext* pc = (NormalizerContext*)pv;
638 return 0;
639 }
640
Preproc_CheckConfig(struct _SnortConfig * sc)641 static int Preproc_CheckConfig (struct _SnortConfig *sc)
642 {
643 int rval;
644
645 if ( !base_set )
646 return 0;
647
648 if ((rval = sfPolicyUserDataIterate(sc, base_set, Preproc_CheckPolicy)))
649 return rval;
650
651 return 0;
652 }
653
Preproc_PostInit(struct _SnortConfig * sc,tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)654 static int Preproc_PostInit (
655 struct _SnortConfig *sc,
656 tSfPolicyUserContextId set,
657 tSfPolicyId pid,
658 void* pv)
659 {
660 NormalizerContext *pc = (NormalizerContext *)pv;
661 SnortPolicy* policy = sc->targeted_policies[pid];
662
663 if ( policy->new_ttl && policy->new_ttl < policy->min_ttl )
664 {
665 policy->new_ttl = policy->min_ttl;
666 }
667 Norm_SetConfig(pc);
668 return 0;
669 }
670
Preproc_PostConfigInit(struct _SnortConfig * sc,void * pv)671 static void Preproc_PostConfigInit (struct _SnortConfig *sc, void* pv)
672 {
673 sfPolicyUserDataIterate(sc, base_set, Preproc_PostInit);
674 }
675
676 //-------------------------------------------------------------------------
677
Preproc_Execute(Packet * p,void * context)678 static void Preproc_Execute (Packet *p, void *context)
679 {
680 tSfPolicyId pid = getNapRuntimePolicy();
681 NormalizerContext* pc = (NormalizerContext*)sfPolicyUserDataGet(base_set, pid);
682 PROFILE_VARS;
683
684 if ( !pc )
685 return;
686
687 PREPROC_PROFILE_START(norm_perf_stats);
688
689 if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )
690 if ( !Active_PacketWasDropped() )
691 if ( pc->normMode == NORM_MODE_ON || pc->normMode == NORM_MODE_WOULDA )
692 Norm_Packet(pc, p);
693
694 PREPROC_PROFILE_END(norm_perf_stats);
695 return;
696 }
697
698 //-------------------------------------------------------------------------
699
Preproc_FreeContext(NormalizerContext * pc)700 static void Preproc_FreeContext (NormalizerContext* pc)
701 {
702 if ( pc )
703 free(pc);
704 }
705
Preproc_FreePolicy(tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)706 static int Preproc_FreePolicy(
707 tSfPolicyUserContextId set,
708 tSfPolicyId pid,
709 void* pv
710 )
711 {
712 NormalizerContext* pc = (NormalizerContext*)pv;
713
714 sfPolicyUserDataClear(set, pid);
715 Preproc_FreeContext(pc);
716
717 return 0;
718 }
719
Preproc_FreeSet(tSfPolicyUserContextId set)720 static void Preproc_FreeSet (tSfPolicyUserContextId set)
721 {
722 if ( !set )
723 return;
724
725 sfPolicyUserDataFreeIterate(set, Preproc_FreePolicy);
726 sfPolicyConfigDelete(set);
727 }
728
729 //-------------------------------------------------------------------------
730
Preproc_CleanExit(int signal,void * foo)731 static void Preproc_CleanExit (int signal, void *foo)
732 {
733 Preproc_FreeSet(base_set);
734 }
735
Preproc_Reset(int signal,void * foo)736 static void Preproc_Reset (int signal, void *foo) { }
737
Preproc_PrintStats(int exiting)738 static void Preproc_PrintStats(int exiting)
739 {
740 if(!ScNapPassiveMode())
741 {
742 Norm_PrintStats();
743 Stream_PrintNormalizationStats();
744 }
745 }
746
Preproc_ResetStats(int signal,void * foo)747 static void Preproc_ResetStats (int signal, void *foo)
748 {
749 Norm_ResetStats();
750 Stream_ResetNormalizationStats();
751 }
752
753 //-------------------------------------------------------------------------
754 // reload stuff
755 //-------------------------------------------------------------------------
756
757 #ifdef SNORT_RELOAD
Reload_GetContext(struct _SnortConfig * sc,void ** new_config)758 static NormalizerContext* Reload_GetContext (struct _SnortConfig *sc, void **new_config)
759 {
760 tSfPolicyUserContextId swap_set;
761 NormalizerContext* pc = NULL;
762 tSfPolicyId policy_id = getParserPolicy(sc);
763
764 if ( ScNapPassiveModeNewConf(sc) )
765 return NULL;
766
767 if (!(swap_set = (tSfPolicyUserContextId)*new_config))
768 if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_ip4")))
769 if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_ip6")))
770 if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_tcp")))
771 if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_icmp4")))
772 swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_icmp6");
773
774 if ( !swap_set )
775 {
776 swap_set = sfPolicyConfigCreate();
777 *new_config = (void *)swap_set;
778 }
779
780 sc->normalizer_set = true;
781
782 sfPolicyUserPolicySet(swap_set, policy_id);
783 pc = sfPolicyUserDataGetCurrent(swap_set);
784
785 if ( !pc )
786 {
787 pc = (NormalizerContext* )SnortAlloc(sizeof(NormalizerContext));
788 sfPolicyUserDataSetCurrent(swap_set, pc);
789
790 if( pc->regFunc != init)
791 {
792 AddFuncToPreprocList(
793 sc, Preproc_Execute, PP_NORMALIZE_PRIORITY, PP_NORMALIZE, PROTO_BITS);
794 pc->regFunc = reload;
795 }
796 session_api->enable_preproc_all_ports( sc, PP_NORMALIZE, PROTO_BITS );
797
798 }
799 if ( sc->targeted_policies[policy_id]->nap_policy_mode == POLICY_MODE__INLINE_TEST )
800 pc->normMode = NORM_MODE_WOULDA;
801 else
802 pc->normMode = NORM_MODE_ON;
803 return pc;
804 }
805
Reload_IP4(struct _SnortConfig * sc,char * args,void ** new_config)806 static void Reload_IP4 (struct _SnortConfig *sc, char* args, void **new_config)
807 {
808 NormalizerContext* pc = Reload_GetContext(sc, new_config);
809
810 if ( pc )
811 Parse_IP4(sc, pc, args);
812 else
813 LogMessage(NOT_INLINE, "ip4");
814 }
815
Reload_ICMP4(struct _SnortConfig * sc,char * args,void ** new_config)816 static void Reload_ICMP4 (struct _SnortConfig *sc, char* args, void **new_config)
817 {
818 NormalizerContext* pc = Reload_GetContext(sc, new_config);
819
820 if ( pc )
821 Parse_ICMP4(pc, args);
822 else
823 LogMessage(NOT_INLINE, "icmp4");
824 }
825
Reload_IP6(struct _SnortConfig * sc,char * args,void ** new_config)826 static void Reload_IP6 (struct _SnortConfig *sc, char* args, void **new_config)
827 {
828 NormalizerContext* pc = Reload_GetContext(sc, new_config);
829
830 if ( pc )
831 Parse_IP6(sc, pc, args);
832 else
833 LogMessage(NOT_INLINE, "ip6");
834 }
835
Reload_ICMP6(struct _SnortConfig * sc,char * args,void ** new_config)836 static void Reload_ICMP6 (struct _SnortConfig *sc, char* args, void **new_config)
837 {
838 NormalizerContext* pc = Reload_GetContext(sc, new_config);
839
840 if ( pc )
841 Parse_ICMP6(pc, args);
842 else
843 LogMessage(NOT_INLINE, "icmp6");
844 }
845
Reload_TCP(struct _SnortConfig * sc,char * args,void ** new_config)846 static void Reload_TCP (struct _SnortConfig *sc, char* args, void **new_config)
847 {
848 NormalizerContext* pc = Reload_GetContext(sc, new_config);
849
850 if ( pc )
851 Parse_TCP(pc, args);
852 else
853 LogMessage(NOT_INLINE, "tcp");
854 }
855
856 //-------------------------------------------------------------------------
857
Reload_VerifyPolicy(struct _SnortConfig * sc,tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)858 static int Reload_VerifyPolicy (
859 struct _SnortConfig *sc,
860 tSfPolicyUserContextId set,
861 tSfPolicyId pid,
862 void* pv
863 ) {
864 //NormalizerContext* pc = (NormalizerContext*)pv;
865 SnortPolicy* policy = sc->targeted_policies[pid];
866 if ( policy->new_ttl && policy->new_ttl < policy->min_ttl )
867 {
868 policy->new_ttl = policy->min_ttl;
869 }
870 return 0;
871 }
872
Reload_Verify(struct _SnortConfig * sc,void * swap_config)873 static int Reload_Verify(struct _SnortConfig *sc, void *swap_config)
874 {
875 int rval;
876 tSfPolicyUserContextId swap_set = (tSfPolicyUserContextId)swap_config;
877
878 if ( !swap_set )
879 return -1;
880
881 if ((rval = sfPolicyUserDataIterate (sc, swap_set, Reload_VerifyPolicy)))
882 return rval;
883
884 return 0;
885 }
886
887 //-------------------------------------------------------------------------
888
Reload_SwapPolicy(tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)889 static int Reload_SwapPolicy (
890 tSfPolicyUserContextId set,
891 tSfPolicyId pid,
892 void* pv)
893 {
894 NormalizerContext* pc = (NormalizerContext*)pv;
895
896 sfPolicyUserDataClear(set, pid);
897 Preproc_FreeContext(pc);
898
899 return 0;
900 }
901
Reload_Swap(struct _SnortConfig * sc,void * swap_config)902 static void* Reload_Swap (struct _SnortConfig *sc, void *swap_config)
903 {
904 tSfPolicyUserContextId swap_set = (tSfPolicyUserContextId)swap_config;
905 tSfPolicyUserContextId old_set = base_set;
906
907 if ( !swap_set )
908 return NULL;
909
910 base_set = swap_set;
911
912 sfPolicyUserDataIterate(sc, base_set, Preproc_PostInit);
913
914 if ( old_set )
915 {
916 sfPolicyUserDataFreeIterate(old_set, Reload_SwapPolicy);
917
918 if ( !sfPolicyUserPolicyGetActive(old_set) )
919 return (void*)old_set;
920 }
921 return NULL;
922 }
923
924 //-------------------------------------------------------------------------
925
Reload_Free(void * pv)926 static void Reload_Free (void* pv)
927 {
928 if ( !pv )
929 return;
930
931 Preproc_FreeSet((tSfPolicyUserContextId)pv);
932 }
933 #endif
934
935 //-------------------------------------------------------------------------
936 // public methods
937 //-------------------------------------------------------------------------
938
Normalize_GetMode(const SnortConfig * sc,NormFlags nf)939 NormMode Normalize_GetMode (const SnortConfig* sc, NormFlags nf)
940 {
941 tSfPolicyId pid;
942 NormalizerContext* pc;
943
944 if ( !base_set )
945 return NORM_MODE_OFF;
946
947 if (!sc->normalizer_set)
948 return NORM_MODE_OFF;
949
950 pid = getNapRuntimePolicy();
951 pc = sfPolicyUserDataGet(base_set, pid);
952
953 if ( !pc )
954 return NORM_MODE_OFF;
955
956 if ( Norm_IsEnabled(pc, nf) )
957 return pc->normMode;
958 return NORM_MODE_OFF;
959 }
960
961 #endif // NORMALIZER
962
963