00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 // Copyright (C) 2010-2013 Sourcefire, Inc.
00004 //
00005 // This program is free software; you can redistribute it and/or modify it
00006 // under the terms of the GNU General Public License Version 2 as published
00007 // by the Free Software Foundation. You may not use, modify or distribute
00008 // this program under any other version of the GNU General Public License.
00009 //
00010 // This program is distributed in the hope that it will be useful, but
00011 // WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License along
00016 // with this program; if not, write to the Free Software Foundation, Inc.,
00017 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 //--------------------------------------------------------------------------
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023
00024 #include "normalize.h"
00025
00026 #include "log/messages.h"
00027 #include "main/policy.h"
00028 #include "packet_io/active.h"
00029 #include "packet_io/sfdaq.h"
00030 #include "profiler/profiler.h"
00031 #include "utils/util_cstring.h"
00032
00033 #include "norm_module.h"
00034
00035 #include "main/snort_debug.h"
00036
00037 THREAD_LOCAL ProfileStats norm_perf_stats;
00038 static THREAD_LOCAL uint32_t t_flags = 0;
00039
00040 //-------------------------------------------------------------------------
00041 // printing stuff
00042 //-------------------------------------------------------------------------
00043
00044 #define ON "on"
00045 #define OFF "off"
00046
00047 static inline void LogConf(const char* p, const char* s)
00048 {
00049 LogMessage("%12s: %s\n", p, s);
00050 }
00051
00052 static inline void LogFlag(
00053 const char* p, const NormalizerConfig* nc, NormFlags nf)
00054 {
00055 const char* s = Norm_IsEnabled(nc, nf) ? ON : OFF;
00056 LogConf(p, s);
00057 }
00058
00059 static void Print_IP4(SnortConfig*, const NormalizerConfig* nc)
00060 {
00061 if ( !Norm_IsEnabled(nc, (NormFlags)NORM_IP4_ANY) )
00062 return;
00063
00064 LogFlag("ip4.base", nc, NORM_IP4_BASE);
00065 //LogFlag("ip4.id", nc, NORM_IP4_ID);
00066 LogFlag("ip4.df", nc, NORM_IP4_DF);
00067 LogFlag("ip4.rf", nc, NORM_IP4_RF);
00068 LogFlag("ip4.tos", nc, NORM_IP4_TOS);
00069 LogFlag("ip4.trim", nc, NORM_IP4_TRIM);
00070
00071 if ( Norm_IsEnabled(nc, NORM_IP4_TTL) )
00072 {
00073 NetworkPolicy* policy = get_network_policy();
00074 LogMessage("%12s: %s (min=%d, new=%d)\n", "ip4.ttl", ON,
00075 policy->min_ttl, policy->new_ttl);
00076 }
00077 else
00078 LogConf("ip4.ttl", OFF);
00079 }
00080
00081 static void Print_ICMP4(const NormalizerConfig* nc)
00082 {
00083 LogFlag("icmp4", nc, NORM_ICMP4);
00084 }
00085
00086 static void Print_IP6(SnortConfig*, const NormalizerConfig* nc)
00087 {
00088 if ( !Norm_IsEnabled(nc, (NormFlags)NORM_IP6_ANY) )
00089 return;
00090
00091 LogFlag("ip6.base", nc, NORM_IP6_BASE);
00092
00093 if ( Norm_IsEnabled(nc, NORM_IP6_TTL) )
00094 {
00095 NetworkPolicy* policy = get_network_policy();
00096 LogMessage("%12s: %s (min=%d, new=%d)\n", "ip6.hops",
00097 ON, policy->min_ttl, policy->new_ttl);
00098 }
00099 }
00100
00101 static void Print_ICMP6(const NormalizerConfig* nc)
00102 {
00103 LogFlag("icmp6", nc, NORM_ICMP6);
00104 }
00105
00106 static void Print_TCP(const NormalizerConfig* nc)
00107 {
00108 if ( !Norm_IsEnabled(nc, (NormFlags)NORM_TCP_ANY) )
00109 return;
00110
00111 const char* s;
00112
00113 if ( Norm_IsEnabled(nc, NORM_TCP_ECN_PKT) )
00114 s = "packet";
00115 else if ( Norm_IsEnabled(nc, NORM_TCP_ECN_STR) )
00116 s = "stream";
00117 else
00118 s = OFF;
00119
00120 LogConf("tcp.ecn", s);
00121 LogFlag("tcp.block", nc, NORM_TCP_BLOCK);
00122 LogFlag("tcp.rsv", nc, NORM_TCP_RSV);
00123 LogFlag("tcp.pad", nc, NORM_TCP_PAD);
00124 LogFlag("tcp.req_urg", nc, NORM_TCP_REQ_URG);
00125 LogFlag("tcp.req_pay", nc, NORM_TCP_REQ_PAY);
00126 LogFlag("tcp.req_urp", nc, NORM_TCP_REQ_URP);
00127 LogFlag("tcp.urp", nc, NORM_TCP_URP);
00128
00129 if ( Norm_IsEnabled(nc, NORM_TCP_OPT) )
00130 {
00131 char buf[1024];
00132 char* p = buf;
00133 int opt;
00134 int buf_size = sizeof(buf);
00135
00136 int len = safe_snprintf(p, buf_size, "%s", "(allow ");
00137 p += len;
00138 buf_size -= len;
00139 bool opt_printed = false;
00140 // TBD translate options to keywords allowed by parser
00141 for ( opt = 2; opt < 256; opt++ )
00142 {
00143 if ( Norm_TcpIsOptional(nc, opt) )
00144 {
00145 const char* fmt = opt_printed ? ",%d" : "%d";
00146 len = safe_snprintf(p, buf_size, fmt, opt);
00147 if (len >0)
00148 opt_printed = true;
00149 p += len;
00150 buf_size -= len;
00151 }
00152 }
00153 snprintf(p, buf_size, "%c", ')');
00154 LogMessage("%12s: %s %s\n", "tcp.opt", ON, buf);
00155 }
00156 else
00157 LogConf("tcp.opt", OFF);
00158
00159 LogFlag("tcp.ips", nc, NORM_TCP_IPS);
00160 LogFlag("tcp.trim_syn", nc, NORM_TCP_TRIM_SYN);
00161 LogFlag("tcp.trim_rst", nc, NORM_TCP_TRIM_RST);
00162 LogFlag("tcp.trim_win", nc, NORM_TCP_TRIM_WIN);
00163 LogFlag("tcp.trim_mss", nc, NORM_TCP_TRIM_MSS);
00164 }
00165
00166 //-------------------------------------------------------------------------
00167 // class stuff
00168 //-------------------------------------------------------------------------
00169
00170 class Normalizer : public Inspector
00171 {
00172 public:
00173 Normalizer(const NormalizerConfig&);
00174
00175 bool configure(SnortConfig*) override;
00176 void show(SnortConfig*) override;
00177 void eval(Packet*) override;
00178
00179 private:
00180 NormalizerConfig config;
00181 };
00182
00183 Normalizer::Normalizer(const NormalizerConfig& nc)
00184 {
00185 config = nc;
00186 }
00187
00188 // FIXIT-L this works with one normalizer per policy
00189 // but would be better if binder could select
00190 // in which case normal_mask must be moved to flow
00191 bool Normalizer::configure(SnortConfig*)
00192 {
00193 PolicyMode mode = get_ips_policy()->policy_mode;
00194 // FIXIT-L norm needs a nap policy mode
00195 if ( mode == POLICY_MODE__PASSIVE )
00196 {
00197 config.normalizer_flags = 0;
00198 return true;
00199 }
00200
00201 NetworkPolicy* nap = get_network_policy();
00202 nap->normal_mask = config.normalizer_flags;
00203
00204 if ( nap->new_ttl && nap->new_ttl < nap->min_ttl )
00205 {
00206 nap->new_ttl = nap->min_ttl;
00207 }
00208
00209 config.norm_mode = (mode == POLICY_MODE__INLINE) ? NORM_MODE_ON : NORM_MODE_TEST;
00210 Norm_SetConfig(&config);
00211 return true;
00212 }
00213
00214 // FIXIT-L norm flags check should be moved to flow
00215 // set flow flags once at start of flow
00216 bool Normalize_IsEnabled(NormFlags nf)
00217 {
00218 if ( !(t_flags & nf) )
00219 return false;
00220
00221 NetworkPolicy* nap = get_network_policy();
00222 return ( (nap->normal_mask & nf) != 0 );
00223 }
00224
00225 NormMode Normalize_GetMode(NormFlags nf)
00226 {
00227 if (Normalize_IsEnabled(nf))
00228 {
00229 const PolicyMode mode = get_ips_policy()->policy_mode;
00230
00231 if ( mode == POLICY_MODE__INLINE )
00232 return NORM_MODE_ON;
00233
00234 else if ( mode == POLICY_MODE__INLINE_TEST )
00235 return NORM_MODE_TEST;
00236 }
00237 return NORM_MODE_TEST;
00238 }
00239
00240 void Normalizer::show(SnortConfig* sc)
00241 {
00242 LogMessage("Normalizer config:\n");
00243 Print_IP4(sc, &config);
00244 Print_IP6(sc, &config);
00245 Print_ICMP4(&config);
00246 Print_ICMP6(&config);
00247 Print_TCP(&config);
00248 }
00249
00250 void Normalizer::eval(Packet* p)
00251 {
00252 Profile profile(norm_perf_stats);
00253
00254 new_invoked_inspector(4, p, 0);
00255
00256 if ( !p->is_rebuilt() && !Active::packet_was_dropped() )
00257 Norm_Packet(&config, p);
00258 }
00259
00260 //-------------------------------------------------------------------------
00261 // api stuff
00262 //-------------------------------------------------------------------------
00263
00264 static Module* mod_ctor()
00265 { return new NormalizeModule; }
00266
00267 static void mod_dtor(Module* m)
00268 { delete m; }
00269
00270 static Inspector* no_ctor(Module* m)
00271 {
00272 NormalizeModule* mod = (NormalizeModule*)m;
00273 return new Normalizer(*mod->get_config());
00274 }
00275
00276 static void no_dtor(Inspector* p)
00277 {
00278 delete p;
00279 }
00280
00281 static void no_tinit()
00282 {
00283 if ( SFDAQ::can_replace() )
00284 t_flags = NORM_ALL;
00285
00286 if ( !SFDAQ::can_inject() )
00287 t_flags &= ~NORM_IP4_TRIM;
00288 }
00289
00290 static const InspectApi no_api =
00291 {
00292 {
00293 PT_INSPECTOR,
00294 sizeof(InspectApi),
00295 INSAPI_VERSION,
00296 0,
00297 API_RESERVED,
00298 API_OPTIONS,
00299 NORM_NAME,
00300 NORM_HELP,
00301 mod_ctor,
00302 mod_dtor
00303 },
00304 IT_PACKET,
00305 (uint16_t)PktType::ANY_IP,
00306 nullptr, // buffers
00307 nullptr, // service
00308 nullptr, // pinit
00309 nullptr, // pterm
00310 no_tinit,
00311 nullptr, // tterm
00312 no_ctor,
00313 no_dtor,
00314 nullptr, // ssn
00315 nullptr // reset
00316 };
00317
00318 const BaseApi* nin_normalize = &no_api.base;
00319
END OF CODE