<div class="literalblock">\r
<div class="content">\r
<pre><code> ,,_ -*> Snort++ <*-\r
-o" )~ Version 3.0.0-a2 (Build 163) from 2.9.7-177\r
+o" )~ Version 3.0.0-a2 (Build 167) from 2.9.7-177\r
'''' By Martin Roesch & The Snort Team\r
http://snort.org/contact#team\r
Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved.\r
<div class="literalblock">\r
<div class="content">\r
<pre><code>export LUA_PATH=$my_path/include/snort/lua/\?.lua\;\;\r
-export SNORT_LUA_PATH=$my_path/etc</code></pre>\r
+export SNORT_LUA_PATH=$my_path/etc/snort</code></pre>\r
</div></div>\r
<div class="paragraph"><p>Then give it a go:</p></div>\r
<div class="ulist"><ul>\r
</p>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>$my_path/bin/snort -c $my_path/etc/snort.lua\r
-$my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules</code></pre>\r
+<pre><code>$my_path/bin/snort -c $my_path/etc/snort/snort.lua\r
+$my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules</code></pre>\r
</div></div>\r
</li>\r
<li>\r
</p>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>$my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules \\r
+<pre><code>$my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \\r
-r <pcap> -A alert_test -n 100000</code></pre>\r
</div></div>\r
</li>\r
</p>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>$my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules \\r
+<pre><code>$my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \\r
-r <pcap> -A alert_test -n 100000 --lua "suppress = { { gid = 1, sid = 2123 } }"</code></pre>\r
</div></div>\r
</li>\r
</p>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>$my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules \\r
+<pre><code>$my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \\r
--pcap-filter \*.pcap --pcap-dir <dir> -A alert_fast -n 1000 --max-packet-threads 8</code></pre>\r
</div></div>\r
</li>\r
</ul></div>\r
+<div class="paragraph"><p>For more examples, see the usage section.</p></div>\r
</div>\r
<div class="sect2">\r
<h3 id="_tips">Tips</h3>\r
</li>\r
<li>\r
<p>\r
-select <strong>search_engine.search_method</strong> = ac_bnfa_q: set fast pattern algorithm - choose available search engine { ac_banded | ac_bnfa | ac_bnfa_q | ac_full | ac_full_q | ac_sparse | ac_sparse_bands | ac_std }\r
+dynamic <strong>search_engine.search_method</strong> = ac_bnfa_q: set fast pattern algorithm - choose available search engine { ac_banded | ac_bnfa | ac_bnfa_q | ac_full | ac_full_q | ac_sparse | ac_sparse_bands | ac_std }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-enum <strong>snort.-k</strong> = all: <mode> checksum mode (all,noip,notcp,noudp,noicmp,none) { all|noip|notcp|noudp|noicmp|none }\r
+enum <strong>snort.-k</strong> = all: <mode> checksum mode; default is all { all|noip|notcp|noudp|noicmp|none }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-int <strong>snort.-s</strong> = 1514: <snap> (same as --snaplen) { 68:65535 }\r
+int <strong>snort.-s</strong> = 1514: <snap> (same as --snaplen); default is 1514 { 68:65535 }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-int <strong>snort.-z</strong> = 1: <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by the system { 0: }\r
+int <strong>snort.-z</strong> = 1: <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by the system; default is 1 { 0: }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-string <strong>snort.--script-path</strong>: <path> where to find luajit scripts\r
+string <strong>snort.--script-path</strong>: <path> to a luajit script or directory containing luajit scripts\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
+select <strong>snort.--unit-test</strong>: <verbosity> run unit tests with given libcheck output mode { silent | minimal | normal | verbose | env (export CK_VERBOSITY) }\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
implied <strong>snort.--version</strong>: show version number (same as -V)\r
</p>\r
</li>\r
bool <strong>new_http_inspect.test_output</strong> = false: print out HTTP section data\r
</p>\r
</li>\r
+<li>\r
+<p>\r
+int <strong>new_http_inspect.request_depth</strong> = -1: maximum request message body bytes to examine (-1 no limit) { -1: }\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+int <strong>new_http_inspect.response_depth</strong> = -1: maximum response message body bytes to examine (-1 no limit) { -1: }\r
+</p>\r
+</li>\r
</ul></div>\r
<div class="paragraph"><p>Rules:</p></div>\r
<div class="ulist"><ul>\r
</li>\r
<li>\r
<p>\r
-int <strong>perf_monitor.max_file_size</strong> = 4096: files will be rolled over if they exceed this size { 4096: }\r
+int <strong>perf_monitor.max_file_size</strong> = 4294967295: files will be rolled over if they exceed this size { 4096: }\r
</p>\r
</li>\r
<li>\r
plugin function.)</p></div>\r
</div>\r
<div class="sect2">\r
+<h3 id="_developers_guide">Developers Guide</h3>\r
+<div class="paragraph"><p>Run doc/dev_guide.sh to generate /tmp/dev_guide.html, an annotated guide to\r
+the source tree.</p></div>\r
+</div>\r
+<div class="sect2">\r
<h3 id="_piglet_test_harness">Piglet Test Harness</h3>\r
<div class="paragraph"><p>In order to assist with plugin development, an experimental mode called "piglet" mode\r
is provided. With piglet mode, you can call individual methods for a specific plugin.\r
<pre><code>plugin =\r
{\r
type = "piglet",\r
- version = 1\r
-}</code></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>piglet =\r
-{\r
- name = "my_test_for_ipv4_codec",\r
- type = "codec",\r
- target = "ipv4",\r
+ name = "codec::ipv4",\r
+ use_defaults = true,\r
test = function()\r
- local raw_data = RawData.new(1024)\r
+ local daq_header = DAQHeader.new()\r
+ local raw_buffer = RawBuffer.new("some data")\r
local codec_data = CodecData.new()\r
local decode_data = DecodeData.new()</code></pre>\r
</div></div>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code> codec("decode", raw_data, codec_data, decode_data)\r
- return true\r
+<pre><code> return Codec.decode(\r
+ daq_header,\r
+ raw_buffer,\r
+ codec_data,\r
+ decode_data\r
+ )\r
end\r
}</code></pre>\r
</div></div>\r
-<div class="paragraph"><p>More example tests can be found in the piglet_scripts directory. Refer to these\r
-examples for furthur usage of Lua wrappers to snort data structures (such as Packet).</p></div>\r
<div class="paragraph"><p>To run snort in piglet mode, first build snort with the BUILD_PIGLET option turned on\r
(pass the flag -DBUILD_PIGLET:BOOL=ON in cmake).</p></div>\r
<div class="paragraph"><p>Then, run the following command:</p></div>\r
the results of each test script.</p></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_developers_guide">Developers Guide</h3>\r
-<div class="paragraph"><p>Run doc/dev_guide.sh to generate /tmp/dev_guide.html, an annotated guide to\r
-the source tree.</p></div>\r
-</div>\r
-</div>\r
-</div>\r
-<div class="sect1">\r
-<h2 id="_coding_style">Coding Style</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>All new code should try to follow these style guidelines. These are not\r
-yet firm so feedback is welcome to get something we can live with.</p></div>\r
-<div class="sect2">\r
-<h3 id="_general">General</h3>\r
+<h3 id="_piglet_lua_api">Piglet Lua API</h3>\r
+<div class="paragraph"><p>This section documents the API that piglet exposes to Lua.\r
+Refer to the piglet directory in the source tree for examples of usage.</p></div>\r
+<div class="paragraph"><p>Note: Because of the differences between the Lua and C++ data model and type\r
+system, not all parameters map directly to the parameters of the underlying\r
+C\++ member functions. Every effort has been made to keep the mappings consist,\r
+but there are still some differences. They are documented below.</p></div>\r
+<div class="sect3">\r
+<h4 id="_plugin_instances">Plugin Instances</h4>\r
+<div class="paragraph"><p>For each test, piglet instantiates plugin specified in the <code>name</code> field of the\r
+<code>plugin</code> table. The virtual methods of the instance are exposed in a table\r
+unique to each plugin type. The name of the table is the CamelCase name of the\r
+plugin type.</p></div>\r
+<div class="paragraph"><p>For example, codec plugins have a virtual method called <code>decode</code>. This method\r
+is called like this:</p></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>Codec.decode(...)</code></pre>\r
+</div></div>\r
+<div class="paragraph"><p><strong>Codec</strong></p></div>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
-Generally try to follow\r
- <a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml">http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml</a>,\r
- but there are a few differences.\r
+<code>Codec.get_data_link_type() → { int, int, … }</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Each source directory should have a dev_notes.txt file summarizing the\r
- key points for the code in that directory. These are built into the\r
- developers guide.\r
+<code>Codec.get_protocol_ids() → { int, int, … }</code>\r
</p>\r
</li>\r
-</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_naming">Naming</h3>\r
-<div class="ulist"><ul>\r
<li>\r
<p>\r
-Use camel case for namespaces, classes, and types like WhizBangPdfChecker.\r
+<code>Codec.decode(DAQHeader, RawBuffer, CodecData, DecodeData) → bool</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Use lower case identifiers with underscore separators, e.g. some_function()\r
- and my_var.\r
+<code>Codec.log(RawBuffer, uint[lyr_len])</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Use lower case filenames with underscores.\r
+<code>Codec.encode(RawBuffer, EncState, Buffer) → bool</code>\r
</p>\r
</li>\r
-</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_comments">Comments</h3>\r
-<div class="ulist"><ul>\r
<li>\r
<p>\r
-Write comments sparingly with a mind towards future proofing. Often the\r
- comments can be obviated with better code. Clear code is better than a\r
- comment.\r
+<code>Codec.update(uint[flags_hi], uint[flags_lo], RawBuffer, uint[lyr_len] → int</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Function comment blocks are generally just noise that quickly becomes\r
- obsolete. If you absolutely must comment on parameters, put each on a\r
- separate line along with the comment. That way changing the signature\r
- may prompt a change to the comments too.\r
+<code>Codec.format(bool[reverse], RawBuffer, DecodeData)</code>\r
</p>\r
</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Differences:</p></div>\r
+<div class="ulist"><ul>\r
<li>\r
<p>\r
-Use FIXIT (not FIXTHIS or TODO or whatever) to mark things left for a\r
- day or even just a minute. That way we can find them easily and won’t\r
- lose track of them.\r
+In <code>Codec.update()</code>, the <code>(uint64_t) flags</code> parameter has been split into\r
+<code>flags_hi</code> and <code>flags_lo</code>\r
</p>\r
</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>Inspector</strong></p></div>\r
+<div class="ulist"><ul>\r
<li>\r
<p>\r
-Presently using FIXIT-X where X = P | H | M | L, indicating perf, high,\r
- med, or low priority. For now, H, M, or L can indicate alpha 1, 2, or 3.\r
- Perf changes fall between alpha 1 and 2.\r
+<code>Inspector.configure()</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Put the copyright(s) and license in a comment block at the top of each\r
- source file (.h and .cc). Don’t bother with trivial scripts and make\r
- foo. Some interesting Lua code should get a comment block too. Copy and\r
- paste exactly from src/main.h (don’t reformat).\r
+<code>Inspector.tinit()</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Put author, description, etc. in separate comment(s) following the\r
- license. Do not put such comments in the middle of the license foo.\r
- Be sure to put the author line ahead of the header guard to exclude them\r
- from the developers guide.\r
+<code>Inspector.tterm()</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Each header should have a comment immediately after the header guard to\r
- give an overview of the file so the user knows what’s going on.\r
+<code>Inspector.likes(Packet)</code>\r
</p>\r
</li>\r
-</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_logging">Logging</h3>\r
-<div class="ulist"><ul>\r
<li>\r
<p>\r
-Messages intended for the user should not look like debug messages. Eg,\r
- the function name should not be included.\r
+<code>Inspector.eval(Packet)</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Most debug messages should just be deleted.\r
+<code>Inspector.clear(Packet)</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Don’t bang your error messages (no !). The user feels bad enough about the\r
- problem already w/o you shouting at him.\r
+<code>Inspector.get_buf_from_key(string[key], Packet, RawBuffer) → bool</code>\r
</p>\r
</li>\r
-</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_types">Types</h3>\r
-<div class="ulist"><ul>\r
<li>\r
<p>\r
-Use logical types to make the code clearer and to help the compiler catch\r
- problems. typedef uint16_t Port; bool foo(Port) is way better than\r
- int foo(int port).\r
+<code>Inspector.get_buf_from_id(uint[id], Packet, RawBuffer) → bool</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Use forward declarations (e.g. struct SnortConfig;) instead of void*.\r
+<code>Inspector.get_buf_from_type(uint[type], Packet, RawBuffer) → bool</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Try not to use extern data unless absolutely necessary and then put the\r
- extern in an appropriate header.\r
+<code>Inspector.get_splitter(bool[to_server]) → StreamSplitter</code>\r
</p>\r
</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Differences:\r
+* In <code>Inspector.configure()</code>, the <code>SnortConfig*</code> parameter is passed implicitly.\r
+* the overloaded <code>get_buf()</code> member function has been split into three separate methods.</p></div>\r
+<div class="paragraph"><p><strong>IpsOption</strong></p></div>\r
+<div class="ulist"><ul>\r
<li>\r
<p>\r
-Use const liberally. In most cases, const char* s = "foo" should be\r
- const char* const s = "foo". The former goes in the initialized data\r
- section and the latter in read only data section.\r
+<code>IpsOption.hash() → int</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-But use const char s[] = "foo" instead of const char* s = "foo" when\r
- possible. The latter form allocates a pointer variable and the data\r
- while the former allocates only the data.\r
+<code>IpsOption.is_relative() → bool</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Use static wherever possible to minimize public symbols and eliminate\r
- unneeded relocations.\r
+<code>IpsOption.fp_research() → bool</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Declare functions virtual only in the parent class introducing the\r
- function (not in a derived class that is overriding the function).\r
- This makes it clear which class introduces the function.\r
+<code>IpsOption.get_cursor_type() → int</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Declare functions as override if they are intended to override a\r
- function. This makes it possible to find derived implementations that\r
- didn’t get updated and therefore won’t get called due a change in the\r
- parent signature.\r
+<code>IpsOption.eval(Cursor, Packet) → int</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Use bool functions instead of int unless there is truly a need for\r
- multiple error returns. The C-style use of zero for success and -1 for\r
- error is less readable and often leads to messy code that either ignores\r
- the various errors anyway or needlessly and ineffectively tries to do\r
- something aobut them.\r
+<code>IpsOption.action(Packet)</code>\r
</p>\r
</li>\r
</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_macros_aka_defines">Macros (aka defines)</h3>\r
+<div class="paragraph"><p><strong>IpsAction</strong></p></div>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
-In many cases, even in C++, use #define name "value" instead of a\r
- const char* const name = "value" because it will eliminate a symbol from\r
- the binary.\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-Use inline functions instead of macros where possible (pretty much all\r
- cases except where stringification is necessary). Functions offer better\r
- typing, avoid re-expansions, and a debugger can break there.\r
+<code>IpsAction.exec(Packet)</code>\r
</p>\r
</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>Logger</strong></p></div>\r
+<div class="ulist"><ul>\r
<li>\r
<p>\r
-All macros except simple const values should be wrapped in () and all\r
- args should be wrapped in () too to avoid surprises upon expansion.\r
- Example:\r
+<code>Logger.open()</code>\r
</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>#define SEQ_LT(a,b) ((int)((a) - (b)) < 0)</code></pre>\r
-</div></div>\r
</li>\r
<li>\r
<p>\r
-Multiline macros should be blocked (i.e. inside { }) to avoid if-else type\r
- surprises.\r
+<code>Logger.close()</code>\r
</p>\r
</li>\r
-</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_formatting">Formatting</h3>\r
-<div class="ulist"><ul>\r
<li>\r
<p>\r
-Indent 4 space chars … no tabs!\r
+<code>Logger.reset()</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-If you need to indent many times, something could be rewritten or\r
- restructured to make it clearer. Fewer indents is generally easier to\r
- write, easier to read, and overall better code.\r
+<code>Logger.alert(Packet, string[message], Event)</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Braces go on the line immediately following a new scope (function\r
- signature, if, else, loop, switch, etc.\r
+<code>Logger.log(Packet, string[message], Event)</code>\r
</p>\r
</li>\r
-<li>\r
-<p>\r
-Use consistent spacing and line breaks. Always indent 4 spaces from the\r
- breaking line. Keep lines less than 100 chars; it greatly helps\r
- readability.\r
-</p>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>SearchEngine</strong></p></div>\r
+<div class="paragraph"><p>Currently, SearchEngine does not expose any methods.</p></div>\r
+<div class="paragraph"><p><strong>SoRule</strong></p></div>\r
+<div class="paragraph"><p>Currently, SoRule does not expose any methods.</p></div>\r
+<div class="sect4">\r
+<h5 id="_interface_objects">Interface Objects</h5>\r
+<div class="paragraph"><p>Many of the plugins take C++ classes and structs as arguments. These objects\r
+are exposed to the Lua API as Lua userdata. Exposed objects are instantiated\r
+by calling the <code>new</code> method from each object’s method table.</p></div>\r
+<div class="paragraph"><p>For example, the DecodeData object can be instantiated and exposed to Lua\r
+like this:</p></div>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>No:\r
- calling_a_func_with_a_long_name(arg1,\r
- arg2,\r
- arg3);</code></pre>\r
+<pre><code>local decode_data = DecodeData.new(...)</code></pre>\r
</div></div>\r
+<div class="paragraph"><p>Each object also exposes useful methods for getting and setting member variables,\r
+and calling the C++ methods contained in the the object. These methods can\r
+be accessed using the <code>:</code> accessor syntax:</p></div>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>Yes:\r
- calling_a_func_with_a_long_name(\r
- arg1, arg2, arg3);</code></pre>\r
+<pre><code>decode_data:set({ sp = 80, dp = 3500 })</code></pre>\r
</div></div>\r
-</li>\r
-<li>\r
-<p>\r
-Put function signature on one line, except when breaking for the arg\r
- list:\r
-</p>\r
+<div class="paragraph"><p>Since this is just syntactic sugar for passing the object as the first parameter\r
+of the function <code>DecodeData.set</code>, an equivalent form is:</p></div>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>No:\r
- inline\r
- bool foo()\r
- { // ...</code></pre>\r
+<pre><code>decode_data.set(decode_data, { sp = 80, dp = 3500 })</code></pre>\r
</div></div>\r
+<div class="paragraph"><p>or even:</p></div>\r
<div class="literalblock">\r
<div class="content">\r
-<pre><code>Yes:\r
- inline bool foo()\r
- { // ...</code></pre>\r
+<pre><code>DecodeData.set(decode_data, { sp = 80, dp = 3500 })</code></pre>\r
</div></div>\r
-</li>\r
+<div class="paragraph"><p><strong>Buffer</strong></p></div>\r
+<div class="ulist"><ul>\r
<li>\r
<p>\r
-Put conditional code on the line following the if so it is easy to break\r
- on the conditional block:\r
+<code>Buffer.new(string[data]) → Buffer</code>\r
</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>No:\r
- if ( test ) foo();</code></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>Yes:\r
- if ( test )\r
- foo();</code></pre>\r
-</div></div>\r
</li>\r
-</ul></div>\r
-</div>\r
-<div class="sect2">\r
-<h3 id="_headers">Headers</h3>\r
-<div class="ulist"><ul>\r
<li>\r
<p>\r
-Don’t hesitate to create a new header if it is needed. Don’t lump\r
- unrelated stuff into an header because it is convenient.\r
+<code>Buffer.new(uint[length]) → Buffer</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Write header guards like this (leading underscores are reserved for\r
- system stuff). In my_header.h:\r
+<code>Buffer.new(RawBuffer) → Buffer</code>\r
</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>#ifndef MY_HEADER_H\r
-#define MY_HEADER_H\r
-// ...\r
-#endif</code></pre>\r
-</div></div>\r
</li>\r
<li>\r
<p>\r
-Includes from a different directory should specify parent directory.\r
- This makes it clear exactly what is included and avoids the primordial\r
- soup that results from using -I this -I that -I the_other_thing … .\r
+<code>Buffer:allocate(uint[length]) → bool</code>\r
</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>// given:\r
-src/foo/foo.cc\r
-src/bar/bar.cc\r
-src/bar/baz.cc</code></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>// in baz.cc\r
-#include "bar.h"</code></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><code>// in foo.cc\r
-#include "bar/bar.h"</code></pre>\r
-</div></div>\r
</li>\r
<li>\r
<p>\r
-Includes within installed headers should specify parent directory.\r
+<code>Buffer:clear()</code>\r
</p>\r
</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>CodecData</strong></p></div>\r
+<div class="ulist"><ul>\r
<li>\r
<p>\r
-Just because it is a #define doesn’t mean it goes in a header.\r
- Everything should be scoped as tightly as possible. Shared\r
- implementation declarations should go in a separate header from the\r
- interface. And so on.\r
+<code>CodecData.new() → CodecData</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-A .cc should include its own .h before any others (including\r
- system headers). This ensures that the header stands on its own and can\r
- be used by clients without include prerequisites.\r
+<code>CodecData.new(uint[next_prot_id]) → CodecData</code>\r
</p>\r
</li>\r
<li>\r
<p>\r
-Include required headers, all required headers, and nothing but required\r
- headers. Don’t just clone a bunch of headers because it is convenient.\r
+<code>CodecData.new(fields) → CodecData</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>CodecData:get() → fields</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>CodecData:set(fields)</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><code>fields</code> is a table with the following contents:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>next_prot_id</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>lyr_len</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>invalid_bytes</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>proto_bits</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>codec_flags</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ip_layer_cnt</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ip6_extension_count</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>curr_ip6_extension</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ip6_csum_proto</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>Cursor</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>Cursor.new() → Cursor</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor.new(Packet) → Cursor</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor.new(string[data]) → Cursor</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor.new(RawBuffer) → Cursor</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor:reset()</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor:reset(Packet)</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor:reset(string[data])</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Cursor:reset(RawBuffer)</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>DAQHeader</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>DAQHeader.new() → DAQHeader</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DAQHeader.new(fields) → DAQHeader</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DAQHeader:get() → fields</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DAQHeader:set(fields)</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><code>fields</code> is a table with the following contents:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>caplen</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>pktlen</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ingress_index</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>egress_index</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ingress_group</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>egress_group</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>flags</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>opaque</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>DecodeData</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>DecodeData.new() → DecodeData</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DecodeData.new(fields) → DecodeData</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DecodeData:reset()</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DecodeData:get() → fields</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DecodeData:set(fields)</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>DecodeData:set_ipv4_hdr(RawBuffer, uint[offset])</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><code>fields</code> is a table with the following contents:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>sp</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>dp</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>decode_flags</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>type</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>EncState</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>EncState.new() → EncState</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>EncState.new(uint[flags_lo]) → EncState</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>EncState.new(uint[flags_lo], uint[flags_hi]) → EncState</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>EncState.new(uint[flags_lo], uint[flags_hi], uint[next_proto]) → EncState</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>EncState.new(uint[flags_lo], uint[flags_hi], uint[next_proto], uint[ttl]) → EncState</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>EncState.new(uint[flags_lo], uint[flags_hi], uint[next_proto], uint[ttl], uint[dsize]) → EncState</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>Event</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>Event.new() → Event</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Event.new(fields) → Event</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Event:get() → fields</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Event:set(fields)</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><code>fields</code> is a table with the following contents:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>event_id</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>event_reference</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>sig_info</code>\r
+</p>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>generator</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>id</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>rev</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>class_id</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>priority</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>text_rule</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>num_services</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>Flow</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>Flow.new() → Flow</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Flow:reset()</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><strong>Packet</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>Packet.new() → Packet</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet.new(string[data]) → Packet</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet.new(uint[size]) → Packet</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet.new(fields) → Packet</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet.new(RawBuffer) → Packet</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet.new(DAQHeader) → Packet</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set_decode_data(DecodeData)</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set_data(uint[offset], uint[length])</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set_flow(Flow)</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:get() → fields</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set() </code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set(string[data]) </code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set(uint[size]) </code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set(fields) </code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set(RawBuffer) </code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>Packet:set(DAQHeader) </code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p><code>fields</code> is a table with the following contents:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>packet_flags</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>xtradata_mask</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>proto_bits</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>application_protocol_ordinal</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>alt_dsize</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>num_layers</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>iplist_id</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>user_policy_id</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ps_proto</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Note: <code>Packet.new()</code> and <code>Packet:set()</code> accept multiple arguments of the\r
+types described above in any order</p></div>\r
+<div class="paragraph"><p><strong>RawBuffer</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>RawBuffer.new() → RawBuffer</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer.new(uint[size]) → RawBuffer</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer.new(string[data]) → RawBuffer</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:size() → int</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:resize(uint[size])</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:write(string[data])</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:write(string[data], uint[size])</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:read() → string</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:read(uint[end]) → string</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>RawBuffer:read(uint[start], uint[end]) → string</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Note: calling <code>RawBuffer.new()</code> with no arguments returns a RawBuffer of size 0</p></div>\r
+<div class="paragraph"><p><strong>StreamSplitter</strong></p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:scan(Flow, RawBuffer) → int, int</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:scan(Flow, RawBuffer, uint[len]) → int, int</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:scan(Flow, RawBuffer, uint[len], uint[flags]) → int, int</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:reassemble(Flow, uint[total], uint[offset], RawBuffer) → int, RawBuffer</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:reassemble(Flow, uint[total], uint[offset], RawBuffer, uint[len]) → int, RawBuffer</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:reassemble(Flow, uint[total], uint[offset], RawBuffer, uint[len], uint[flags]) → int, RawBuffer</code>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>StreamSplitter:finish(Flow) → bool</code>\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Note: StreamSplitter does not have a <code>new()</code> method, it must be created by an inspector via\r
+<code>Inspector.get_splitter()</code></p></div>\r
+</div>\r
+</div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_coding_style">Coding Style</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>All new code should try to follow these style guidelines. These are not\r
+yet firm so feedback is welcome to get something we can live with.</p></div>\r
+<div class="sect2">\r
+<h3 id="_general">General</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Generally try to follow\r
+ <a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml">http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml</a>,\r
+ but there are a few differences.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Each source directory should have a dev_notes.txt file summarizing the\r
+ key points for the code in that directory. These are built into the\r
+ developers guide.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_naming">Naming</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Use camel case for namespaces, classes, and types like WhizBangPdfChecker.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use lower case identifiers with underscore separators, e.g. some_function()\r
+ and my_var.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use lower case filenames with underscores.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_comments">Comments</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Write comments sparingly with a mind towards future proofing. Often the\r
+ comments can be obviated with better code. Clear code is better than a\r
+ comment.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Function comment blocks are generally just noise that quickly becomes\r
+ obsolete. If you absolutely must comment on parameters, put each on a\r
+ separate line along with the comment. That way changing the signature\r
+ may prompt a change to the comments too.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use FIXIT (not FIXTHIS or TODO or whatever) to mark things left for a\r
+ day or even just a minute. That way we can find them easily and won’t\r
+ lose track of them.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Presently using FIXIT-X where X = P | H | M | L, indicating perf, high,\r
+ med, or low priority. For now, H, M, or L can indicate alpha 1, 2, or 3.\r
+ Perf changes fall between alpha 1 and 2.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Put the copyright(s) and license in a comment block at the top of each\r
+ source file (.h and .cc). Don’t bother with trivial scripts and make\r
+ foo. Some interesting Lua code should get a comment block too. Copy and\r
+ paste exactly from src/main.h (don’t reformat).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Put author, description, etc. in separate comment(s) following the\r
+ license. Do not put such comments in the middle of the license foo.\r
+ Be sure to put the author line ahead of the header guard to exclude them\r
+ from the developers guide.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Each header should have a comment immediately after the header guard to\r
+ give an overview of the file so the user knows what’s going on.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_logging">Logging</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Messages intended for the user should not look like debug messages. Eg,\r
+ the function name should not be included.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Most debug messages should just be deleted.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Don’t bang your error messages (no !). The user feels bad enough about the\r
+ problem already w/o you shouting at him.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_types">Types</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Use logical types to make the code clearer and to help the compiler catch\r
+ problems. typedef uint16_t Port; bool foo(Port) is way better than\r
+ int foo(int port).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use forward declarations (e.g. struct SnortConfig;) instead of void*.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Try not to use extern data unless absolutely necessary and then put the\r
+ extern in an appropriate header.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use const liberally. In most cases, const char* s = "foo" should be\r
+ const char* const s = "foo". The former goes in the initialized data\r
+ section and the latter in read only data section.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+But use const char s[] = "foo" instead of const char* s = "foo" when\r
+ possible. The latter form allocates a pointer variable and the data\r
+ while the former allocates only the data.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use static wherever possible to minimize public symbols and eliminate\r
+ unneeded relocations.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Declare functions virtual only in the parent class introducing the\r
+ function (not in a derived class that is overriding the function).\r
+ This makes it clear which class introduces the function.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Declare functions as override if they are intended to override a\r
+ function. This makes it possible to find derived implementations that\r
+ didn’t get updated and therefore won’t get called due a change in the\r
+ parent signature.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use bool functions instead of int unless there is truly a need for\r
+ multiple error returns. The C-style use of zero for success and -1 for\r
+ error is less readable and often leads to messy code that either ignores\r
+ the various errors anyway or needlessly and ineffectively tries to do\r
+ something aobut them.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_macros_aka_defines">Macros (aka defines)</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+In many cases, even in C++, use #define name "value" instead of a\r
+ const char* const name = "value" because it will eliminate a symbol from\r
+ the binary.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use inline functions instead of macros where possible (pretty much all\r
+ cases except where stringification is necessary). Functions offer better\r
+ typing, avoid re-expansions, and a debugger can break there.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+All macros except simple const values should be wrapped in () and all\r
+ args should be wrapped in () too to avoid surprises upon expansion.\r
+ Example:\r
+</p>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>#define SEQ_LT(a,b) ((int)((a) - (b)) < 0)</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Multiline macros should be blocked (i.e. inside { }) to avoid if-else type\r
+ surprises.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_formatting">Formatting</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Indent 4 space chars … no tabs!\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+If you need to indent many times, something could be rewritten or\r
+ restructured to make it clearer. Fewer indents is generally easier to\r
+ write, easier to read, and overall better code.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Braces go on the line immediately following a new scope (function\r
+ signature, if, else, loop, switch, etc.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Use consistent spacing and line breaks. Always indent 4 spaces from the\r
+ breaking line. Keep lines less than 100 chars; it greatly helps\r
+ readability.\r
+</p>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>No:\r
+ calling_a_func_with_a_long_name(arg1,\r
+ arg2,\r
+ arg3);</code></pre>\r
+</div></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>Yes:\r
+ calling_a_func_with_a_long_name(\r
+ arg1, arg2, arg3);</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Put function signature on one line, except when breaking for the arg\r
+ list:\r
+</p>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>No:\r
+ inline\r
+ bool foo()\r
+ { // ...</code></pre>\r
+</div></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>Yes:\r
+ inline bool foo()\r
+ { // ...</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Put conditional code on the line following the if so it is easy to break\r
+ on the conditional block:\r
+</p>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>No:\r
+ if ( test ) foo();</code></pre>\r
+</div></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>Yes:\r
+ if ( test )\r
+ foo();</code></pre>\r
+</div></div>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_headers">Headers</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Don’t hesitate to create a new header if it is needed. Don’t lump\r
+ unrelated stuff into an header because it is convenient.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Write header guards like this (leading underscores are reserved for\r
+ system stuff). In my_header.h:\r
+</p>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>#ifndef MY_HEADER_H\r
+#define MY_HEADER_H\r
+// ...\r
+#endif</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Includes from a different directory should specify parent directory.\r
+ This makes it clear exactly what is included and avoids the primordial\r
+ soup that results from using -I this -I that -I the_other_thing … .\r
+</p>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>// given:\r
+src/foo/foo.cc\r
+src/bar/bar.cc\r
+src/bar/baz.cc</code></pre>\r
+</div></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>// in baz.cc\r
+#include "bar.h"</code></pre>\r
+</div></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>// in foo.cc\r
+#include "bar/bar.h"</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Includes within installed headers should specify parent directory.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Just because it is a #define doesn’t mean it goes in a header.\r
+ Everything should be scoped as tightly as possible. Shared\r
+ implementation declarations should go in a separate header from the\r
+ interface. And so on.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+A .cc should include its own .h before any others (including\r
+ system headers). This ensures that the header stands on its own and can\r
+ be used by clients without include prerequisites.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Include required headers, all required headers, and nothing but required\r
+ headers. Don’t just clone a bunch of headers because it is convenient.\r
</p>\r
</li>\r
<li>\r
<pre><code>snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \\r
--pcap-filter '*.pcap' --max-packet-threads 8</code></pre>\r
</div></div>\r
+<div class="paragraph"><p>Run Snort++ on 2 interfaces, eth0 and eth1:</p></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>snort -c $my_path/etc/snort/snort.lua -i "eth0 eth1" -z 2 -A cmg</code></pre>\r
+</div></div>\r
+<div class="paragraph"><p>Run Snort++ inline with the afpacket DAQ:</p></div>\r
+<div class="literalblock">\r
+<div class="content">\r
+<pre><code>snort -c $my_path/etc/snort/snort.lua --daq afpacket -i "eth0:eth1" \\r
+ -A cmg</code></pre>\r
+</div></div>\r
</div>\r
</div>\r
<div class="sect2">\r
</li>\r
<li>\r
<p>\r
-<strong>--dump-defaults</strong> [<module prefix>] output module defaults in Lua format\r
+<strong>--dump-defaults</strong> [<module prefix>] output module defaults in Lua format (optional)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--dump-version</strong> output the version, the whole version, and only the version\r
+<strong>--dump-version</strong> output the version, the whole version, and only the version (optional)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--help-commands</strong> [<module prefix>] output matching commands\r
+<strong>--help-commands</strong> [<module prefix>] output matching commands (optional)\r
</p>\r
</li>\r
<li>\r
<p>\r
-<strong>--help-config</strong> [<module prefix>] output matching config options\r
+<strong>--help-config</strong> [<module prefix>] output matching config options (optional)\r
</p>\r
</li>\r
<li>\r
<p>\r
-<strong>--help-counts</strong> [<module prefix>] output matching peg counts\r
+<strong>--help-counts</strong> [<module prefix>] output matching peg counts (optional)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--help-options</strong> <option prefix> output matching command line option quick help (same as -?)\r
+<strong>--help-options</strong> <option prefix> output matching command line option quick help (same as -?) (optional)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--list-builtin</strong> <module prefix> output matching builtin rules\r
+<strong>--list-builtin</strong> <module prefix> output matching builtin rules (optional)\r
</p>\r
</li>\r
<li>\r
<p>\r
-<strong>--list-gids</strong> [<module prefix>] output matching generators\r
+<strong>--list-gids</strong> [<module prefix>] output matching generators (optional)\r
</p>\r
</li>\r
<li>\r
<p>\r
-<strong>--list-modules</strong> [<module type>] list all known modules of given type\r
+<strong>--list-modules</strong> [<module type>] list all known modules of given type (optional)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--logid</strong> <0xid> log Identifier to uniquely id events for multiple snorts (same as -G)\r
+<strong>--logid</strong> <0xid> log Identifier to uniquely id events for multiple snorts (same as -G) (0:65535)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--max-packet-threads</strong> <count> configure maximum number of packet threads (same as -z)\r
+<strong>--max-packet-threads</strong> <count> configure maximum number of packet threads (same as -z) (0:)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--pcap-loop</strong> <count> read all pcaps <count> times; 0 will read until Snort is terminated\r
+<strong>--pcap-loop</strong> <count> read all pcaps <count> times; 0 will read until Snort is terminated (-1:)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--script-path</strong> <path> where to find luajit scripts\r
+<strong>--script-path</strong> <path> to a luajit script or directory containing luajit scripts\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>--skip</strong> <n> skip 1st n packets\r
+<strong>--skip</strong> <n> skip 1st n packets (0:)\r
</p>\r
</li>\r
<li>\r
<p>\r
-<strong>--snaplen</strong> <snap> set snaplen of packet (same as -s)\r
+<strong>--snaplen</strong> <snap> set snaplen of packet (same as -s) (68:65535)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
+<strong>--unit-test</strong> <verbosity> run unit tests with given libcheck output mode (silent | minimal | normal | verbose | env (export CK_VERBOSITY))\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
<strong>--version</strong> show version number (same as -V)\r
</p>\r
</li>\r
</li>\r
<li>\r
<p>\r
-<strong>-?</strong> <option prefix> output matching command line option quick help (same as --help-options)\r
+<strong>-?</strong> <option prefix> output matching command line option quick help (same as --help-options) (optional)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>-G</strong> <0xid> (same as --logid)\r
+<strong>-G</strong> <0xid> (same as --logid) (0:65535)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>-k</strong> <mode> checksum mode (all,noip,notcp,noudp,noicmp,none)\r
+<strong>-k</strong> <mode> checksum mode; default is all (all|noip|notcp|noudp|noicmp|none)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>-m</strong> <umask> set umask = <umask>\r
+<strong>-m</strong> <umask> set umask = <umask> (0:)\r
</p>\r
</li>\r
<li>\r
<p>\r
-<strong>-n</strong> <count> stop after count packets\r
+<strong>-n</strong> <count> stop after count packets (0:)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>-s</strong> <snap> (same as --snaplen)\r
+<strong>-s</strong> <snap> (same as --snaplen); default is 1514 (68:65535)\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-<strong>-z</strong> <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by the system\r
+<strong>-z</strong> <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by the system; default is 1 (0:)\r
</p>\r
</li>\r
</ul></div>\r
</li>\r
<li>\r
<p>\r
+<strong>dynamic</strong>: a select type determined by loaded plugins\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
<strong>enum</strong>: a string selected from the given range\r
</p>\r
</li>\r
</li>\r
<li>\r
<p>\r
+int <strong>new_http_inspect.request_depth</strong> = -1: maximum request message body bytes to examine (-1 no limit) { -1: }\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+int <strong>new_http_inspect.response_depth</strong> = -1: maximum response message body bytes to examine (-1 no limit) { -1: }\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
bool <strong>new_http_inspect.test_input</strong> = false: read HTTP messages from text file\r
</p>\r
</li>\r
</li>\r
<li>\r
<p>\r
-int <strong>perf_monitor.max_file_size</strong> = 4096: files will be rolled over if they exceed this size { 4096: }\r
+int <strong>perf_monitor.max_file_size</strong> = 4294967295: files will be rolled over if they exceed this size { 4096: }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-select <strong>search_engine.search_method</strong> = ac_bnfa_q: set fast pattern algorithm - choose available search engine { ac_banded | ac_bnfa | ac_bnfa_q | ac_full | ac_full_q | ac_sparse | ac_sparse_bands | ac_std }\r
+dynamic <strong>search_engine.search_method</strong> = ac_bnfa_q: set fast pattern algorithm - choose available search engine { ac_banded | ac_bnfa | ac_bnfa_q | ac_full | ac_full_q | ac_sparse | ac_sparse_bands | ac_std | lowmem | lowmem_q }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-string <strong>snort.--script-path</strong>: <path> where to find luajit scripts\r
+string <strong>snort.--script-path</strong>: <path> to a luajit script or directory containing luajit scripts\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
+select <strong>snort.--unit-test</strong>: <verbosity> run unit tests with given libcheck output mode { silent | minimal | normal | verbose | env (export CK_VERBOSITY) }\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
implied <strong>snort.--version</strong>: show version number (same as -V)\r
</p>\r
</li>\r
</li>\r
<li>\r
<p>\r
-enum <strong>snort.-k</strong> = all: <mode> checksum mode (all,noip,notcp,noudp,noicmp,none) { all|noip|notcp|noudp|noicmp|none }\r
+enum <strong>snort.-k</strong> = all: <mode> checksum mode; default is all { all|noip|notcp|noudp|noicmp|none }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-int <strong>snort.-s</strong> = 1514: <snap> (same as --snaplen) { 68:65535 }\r
+int <strong>snort.-s</strong> = 1514: <snap> (same as --snaplen); default is 1514 { 68:65535 }\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
-int <strong>snort.-z</strong> = 1: <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by the system { 0: }\r
+int <strong>snort.-z</strong> = 1: <count> maximum number of packet threads (same as --max-packet-threads); 0 gets the number of CPU cores reported by the system; default is 1 { 0: }\r
</p>\r
</li>\r
<li>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Last updated 2015-07-31 10:11:05 EDT\r
+Last updated 2015-08-31 11:38:10 EDT\r
</div>\r
</div>\r
</body>\r
14.3. Inspectors
14.4. Codecs
14.5. IPS Actions
- 14.6. Piglet Test Harness
- 14.7. Developers Guide
+ 14.6. Developers Guide
+ 14.7. Piglet Test Harness
+ 14.8. Piglet Lua API
15. Coding Style
Snorty
,,_ -*> Snort++ <*-
-o" )~ Version 3.0.0-a2 (Build 163) from 2.9.7-177
+o" )~ Version 3.0.0-a2 (Build 167) from 2.9.7-177
'''' By Martin Roesch & The Snort Team
http://snort.org/contact#team
Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved.
First set up the environment:
export LUA_PATH=$my_path/include/snort/lua/\?.lua\;\;
-export SNORT_LUA_PATH=$my_path/etc
+export SNORT_LUA_PATH=$my_path/etc/snort
Then give it a go:
* Verify config, with or w/o rules:
- $my_path/bin/snort -c $my_path/etc/snort.lua
- $my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules
+ $my_path/bin/snort -c $my_path/etc/snort/snort.lua
+ $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules
* Run IDS mode. To keep it brief, look at the first n packets in
each file:
- $my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules \
+ $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \
-r <pcap> -A alert_test -n 100000
* Let’s suppress 1:2123. We could edit the conf or just do this:
- $my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules \
+ $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \
-r <pcap> -A alert_test -n 100000 --lua "suppress = { { gid = 1, sid = 2123 } }"
* Go whole hog on a directory with multiple packet threads:
- $my_path/bin/snort -c $my_path/etc/snort.lua -R $my_path/etc/sample.rules \
+ $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \
--pcap-filter \*.pcap --pcap-dir <dir> -A alert_fast -n 1000 --max-packet-threads 8
+For more examples, see the usage section.
+
2.4. Tips
* bool search_engine.inspect_stream_inserts = false: inspect
reassembled payload - disabling is good for performance, bad for
detection
- * select search_engine.search_method = ac_bnfa_q: set fast pattern
+ * dynamic search_engine.search_method = ac_bnfa_q: set fast pattern
algorithm - choose available search engine { ac_banded | ac_bnfa
| ac_bnfa_q | ac_full | ac_full_q | ac_sparse | ac_sparse_bands |
ac_std }
* implied snort.-H: make hash tables deterministic
* string snort.-i: <iface>… list of interfaces
* port snort.-j: <port> to listen for telnet connections
- * enum snort.-k = all: <mode> checksum mode
- (all,noip,notcp,noudp,noicmp,none) { all|noip|notcp|noudp|noicmp|
- none }
+ * enum snort.-k = all: <mode> checksum mode; default is all { all|
+ noip|notcp|noudp|noicmp|none }
* string snort.-L: <mode> logging mode (none, dump, pcap, or log_*)
* string snort.-l: <logdir> log to this directory instead of
current directory
policy
* string snort.-r: <pcap>… (same as --pcap-list)
* string snort.-S: <x=v> set config variable x equal to value v
- * int snort.-s = 1514: <snap> (same as --snaplen) { 68:65535 }
+ * int snort.-s = 1514: <snap> (same as --snaplen); default is 1514
+ { 68:65535 }
* implied snort.-T: test and report on the current Snort
configuration
* string snort.-t: <dir> chroots process to <dir> after
files
* int snort.-z = 1: <count> maximum number of packet threads (same
as --max-packet-threads); 0 gets the number of CPU cores reported
- by the system { 0: }
+ by the system; default is 1 { 0: }
* implied snort.--alert-before-pass: process alert, drop, sdrop, or
reject before pass; default is pass before alert, drop,…
* string snort.--bpf: <filter options> are standard BPF options, as
* implied snort.--rule-to-text: output plain so rule header to
stdout for text rule on stdin
* string snort.--run-prefix: <pfx> prepend this to each output file
- * string snort.--script-path: <path> where to find luajit scripts
+ * string snort.--script-path: <path> to a luajit script or
+ directory containing luajit scripts
* implied snort.--shell: enable the interactive command line
* implied snort.--piglet: enable piglet test harness mode
* implied snort.--show-plugins: list module and plugin versions
reject rules into alert rules during startup
* implied snort.--treat-drop-as-ignore: use drop, sdrop, and reject
rules to ignore session traffic when not inline
+ * select snort.--unit-test: <verbosity> run unit tests with given
+ libcheck output mode { silent | minimal | normal | verbose | env
+ (export CK_VERBOSITY) }
* implied snort.--version: show version number (same as -V)
* implied snort.--warn-all: enable all warnings
* implied snort.--warn-conf: warn about configuration issues
text file
* bool new_http_inspect.test_output = false: print out HTTP section
data
+ * int new_http_inspect.request_depth = -1: maximum request message
+ body bytes to examine (-1 no limit) { -1: }
+ * int new_http_inspect.response_depth = -1: maximum response
+ message body bytes to examine (-1 no limit) { -1: }
Rules:
exit only { 0: }
* int perf_monitor.flow_ip_memcap = 52428800: maximum memory for
flow tracking { 8200: }
- * int perf_monitor.max_file_size = 4096: files will be rolled over
- if they exceed this size { 4096: }
+ * int perf_monitor.max_file_size = 4294967295: files will be rolled
+ over if they exceed this size { 4096: }
* int perf_monitor.flow_ports = 1023: maximum ports to track { 0: }
* bool perf_monitor.reset = true: reset (clear) statistics after
each reporting interval
associated plugin function.)
-14.6. Piglet Test Harness
+14.6. Developers Guide
+
+------------
+
+Run doc/dev_guide.sh to generate /tmp/dev_guide.html, an annotated
+guide to the source tree.
+
+
+14.7. Piglet Test Harness
------------
plugin =
{
type = "piglet",
- version = 1
-}
-
-piglet =
-{
- name = "my_test_for_ipv4_codec",
- type = "codec",
- target = "ipv4",
+ name = "codec::ipv4",
+ use_defaults = true,
test = function()
- local raw_data = RawData.new(1024)
+ local daq_header = DAQHeader.new()
+ local raw_buffer = RawBuffer.new("some data")
local codec_data = CodecData.new()
local decode_data = DecodeData.new()
- codec("decode", raw_data, codec_data, decode_data)
- return true
+ return Codec.decode(
+ daq_header,
+ raw_buffer,
+ codec_data,
+ decode_data
+ )
end
}
-More example tests can be found in the piglet_scripts directory.
-Refer to these examples for furthur usage of Lua wrappers to snort
-data structures (such as Packet).
-
To run snort in piglet mode, first build snort with the BUILD_PIGLET
option turned on (pass the flag -DBUILD_PIGLET:BOOL=ON in cmake).
results of each test script.
-14.7. Developers Guide
+14.8. Piglet Lua API
------------
-Run doc/dev_guide.sh to generate /tmp/dev_guide.html, an annotated
-guide to the source tree.
+This section documents the API that piglet exposes to Lua. Refer to
+the piglet directory in the source tree for examples of usage.
+
+Note: Because of the differences between the Lua and C++ data model
+and type system, not all parameters map directly to the parameters of
+the underlying C\++ member functions. Every effort has been made to
+keep the mappings consist, but there are still some differences. They
+are documented below.
+
+14.8.1. Plugin Instances
+
+For each test, piglet instantiates plugin specified in the name field
+of the plugin table. The virtual methods of the instance are exposed
+in a table unique to each plugin type. The name of the table is the
+CamelCase name of the plugin type.
+
+For example, codec plugins have a virtual method called decode. This
+method is called like this:
+
+Codec.decode(...)
+
+Codec
+
+ * Codec.get_data_link_type() → { int, int, … }
+ * Codec.get_protocol_ids() → { int, int, … }
+ * Codec.decode(DAQHeader, RawBuffer, CodecData, DecodeData) → bool
+ * Codec.log(RawBuffer, uint[lyr_len])
+ * Codec.encode(RawBuffer, EncState, Buffer) → bool
+ * Codec.update(uint[flags_hi], uint[flags_lo], RawBuffer, uint
+ [lyr_len] → int
+ * Codec.format(bool[reverse], RawBuffer, DecodeData)
+
+Differences:
+
+ * In Codec.update(), the (uint64_t) flags parameter has been split
+ into flags_hi and flags_lo
+
+Inspector
+
+ * Inspector.configure()
+ * Inspector.tinit()
+ * Inspector.tterm()
+ * Inspector.likes(Packet)
+ * Inspector.eval(Packet)
+ * Inspector.clear(Packet)
+ * Inspector.get_buf_from_key(string[key], Packet, RawBuffer) → bool
+ * Inspector.get_buf_from_id(uint[id], Packet, RawBuffer) → bool
+ * Inspector.get_buf_from_type(uint[type], Packet, RawBuffer) → bool
+ * Inspector.get_splitter(bool[to_server]) → StreamSplitter
+
+Differences: * In Inspector.configure(), the SnortConfig* parameter
+is passed implicitly. * the overloaded get_buf() member function has
+been split into three separate methods.
+
+IpsOption
+
+ * IpsOption.hash() → int
+ * IpsOption.is_relative() → bool
+ * IpsOption.fp_research() → bool
+ * IpsOption.get_cursor_type() → int
+ * IpsOption.eval(Cursor, Packet) → int
+ * IpsOption.action(Packet)
+
+IpsAction
+
+ * IpsAction.exec(Packet)
+
+Logger
+
+ * Logger.open()
+ * Logger.close()
+ * Logger.reset()
+ * Logger.alert(Packet, string[message], Event)
+ * Logger.log(Packet, string[message], Event)
+
+SearchEngine
+
+Currently, SearchEngine does not expose any methods.
+
+SoRule
+
+Currently, SoRule does not expose any methods.
+
+14.8.1.1. Interface Objects
+
+Many of the plugins take C++ classes and structs as arguments. These
+objects are exposed to the Lua API as Lua userdata. Exposed objects
+are instantiated by calling the new method from each object’s method
+table.
+
+For example, the DecodeData object can be instantiated and exposed to
+Lua like this:
+
+local decode_data = DecodeData.new(...)
+
+Each object also exposes useful methods for getting and setting
+member variables, and calling the C++ methods contained in the the
+object. These methods can be accessed using the : accessor syntax:
+
+decode_data:set({ sp = 80, dp = 3500 })
+
+Since this is just syntactic sugar for passing the object as the
+first parameter of the function DecodeData.set, an equivalent form
+is:
+
+decode_data.set(decode_data, { sp = 80, dp = 3500 })
+
+or even:
+
+DecodeData.set(decode_data, { sp = 80, dp = 3500 })
+
+Buffer
+
+ * Buffer.new(string[data]) → Buffer
+ * Buffer.new(uint[length]) → Buffer
+ * Buffer.new(RawBuffer) → Buffer
+ * Buffer:allocate(uint[length]) → bool
+ * Buffer:clear()
+
+CodecData
+
+ * CodecData.new() → CodecData
+ * CodecData.new(uint[next_prot_id]) → CodecData
+ * CodecData.new(fields) → CodecData
+ * CodecData:get() → fields
+ * CodecData:set(fields)
+
+fields is a table with the following contents:
+
+ * next_prot_id
+ * lyr_len
+ * invalid_bytes
+ * proto_bits
+ * codec_flags
+ * ip_layer_cnt
+ * ip6_extension_count
+ * curr_ip6_extension
+ * ip6_csum_proto
+
+Cursor
+
+ * Cursor.new() → Cursor
+ * Cursor.new(Packet) → Cursor
+ * Cursor.new(string[data]) → Cursor
+ * Cursor.new(RawBuffer) → Cursor
+ * Cursor:reset()
+ * Cursor:reset(Packet)
+ * Cursor:reset(string[data])
+ * Cursor:reset(RawBuffer)
+
+DAQHeader
+
+ * DAQHeader.new() → DAQHeader
+ * DAQHeader.new(fields) → DAQHeader
+ * DAQHeader:get() → fields
+ * DAQHeader:set(fields)
+
+fields is a table with the following contents:
+
+ * caplen
+ * pktlen
+ * ingress_index
+ * egress_index
+ * ingress_group
+ * egress_group
+ * flags
+ * opaque
+
+DecodeData
+
+ * DecodeData.new() → DecodeData
+ * DecodeData.new(fields) → DecodeData
+ * DecodeData:reset()
+ * DecodeData:get() → fields
+ * DecodeData:set(fields)
+ * DecodeData:set_ipv4_hdr(RawBuffer, uint[offset])
+
+fields is a table with the following contents:
+
+ * sp
+ * dp
+ * decode_flags
+ * type
+
+EncState
+
+ * EncState.new() → EncState
+ * EncState.new(uint[flags_lo]) → EncState
+ * EncState.new(uint[flags_lo], uint[flags_hi]) → EncState
+ * EncState.new(uint[flags_lo], uint[flags_hi], uint[next_proto]) →
+ EncState
+ * EncState.new(uint[flags_lo], uint[flags_hi], uint[next_proto],
+ uint[ttl]) → EncState
+ * EncState.new(uint[flags_lo], uint[flags_hi], uint[next_proto],
+ uint[ttl], uint[dsize]) → EncState
+
+Event
+
+ * Event.new() → Event
+ * Event.new(fields) → Event
+ * Event:get() → fields
+ * Event:set(fields)
+
+fields is a table with the following contents:
+
+ * event_id
+ * event_reference
+ * sig_info
+
+ + generator
+ + id
+ + rev
+ + class_id
+ + priority
+ + text_rule
+ + num_services
+
+Flow
+
+ * Flow.new() → Flow
+ * Flow:reset()
+
+Packet
+
+ * Packet.new() → Packet
+ * Packet.new(string[data]) → Packet
+ * Packet.new(uint[size]) → Packet
+ * Packet.new(fields) → Packet
+ * Packet.new(RawBuffer) → Packet
+ * Packet.new(DAQHeader) → Packet
+ * Packet:set_decode_data(DecodeData)
+ * Packet:set_data(uint[offset], uint[length])
+ * Packet:set_flow(Flow)
+ * Packet:get() → fields
+ * Packet:set()
+ * Packet:set(string[data])
+ * Packet:set(uint[size])
+ * Packet:set(fields)
+ * Packet:set(RawBuffer)
+ * Packet:set(DAQHeader)
+
+fields is a table with the following contents:
+
+ * packet_flags
+ * xtradata_mask
+ * proto_bits
+ * application_protocol_ordinal
+ * alt_dsize
+ * num_layers
+ * iplist_id
+ * user_policy_id
+ * ps_proto
+
+Note: Packet.new() and Packet:set() accept multiple arguments of the
+types described above in any order
+
+RawBuffer
+
+ * RawBuffer.new() → RawBuffer
+ * RawBuffer.new(uint[size]) → RawBuffer
+ * RawBuffer.new(string[data]) → RawBuffer
+ * RawBuffer:size() → int
+ * RawBuffer:resize(uint[size])
+ * RawBuffer:write(string[data])
+ * RawBuffer:write(string[data], uint[size])
+ * RawBuffer:read() → string
+ * RawBuffer:read(uint[end]) → string
+ * RawBuffer:read(uint[start], uint[end]) → string
+
+Note: calling RawBuffer.new() with no arguments returns a RawBuffer
+of size 0
+
+StreamSplitter
+
+ * StreamSplitter:scan(Flow, RawBuffer) → int, int
+ * StreamSplitter:scan(Flow, RawBuffer, uint[len]) → int, int
+ * StreamSplitter:scan(Flow, RawBuffer, uint[len], uint[flags]) →
+ int, int
+ * StreamSplitter:reassemble(Flow, uint[total], uint[offset],
+ RawBuffer) → int, RawBuffer
+ * StreamSplitter:reassemble(Flow, uint[total], uint[offset],
+ RawBuffer, uint[len]) → int, RawBuffer
+ * StreamSplitter:reassemble(Flow, uint[total], uint[offset],
+ RawBuffer, uint[len], uint[flags]) → int, RawBuffer
+ * StreamSplitter:finish(Flow) → bool
+
+Note: StreamSplitter does not have a new() method, it must be created
+by an inspector via Inspector.get_splitter()
---------------------------------------------------------------------
snort -c $my_path/etc/snort/snort.lua --pcap-dir /path/to/pcap/dir \
--pcap-filter '*.pcap' --max-packet-threads 8
+Run Snort++ on 2 interfaces, eth0 and eth1:
+
+snort -c $my_path/etc/snort/snort.lua -i "eth0 eth1" -z 2 -A cmg
+
+Run Snort++ inline with the afpacket DAQ:
+
+snort -c $my_path/etc/snort/snort.lua --daq afpacket -i "eth0:eth1" \
+ -A cmg
+
16.3. Plugins
* --dump-builtin-rules [<module prefix>] output stub rules for
selected modules
* --dump-defaults [<module prefix>] output module defaults in Lua
- format
+ format (optional)
* --dump-dynamic-rules output stub rules for all loaded rules
libraries
* --dump-version output the version, the whole version, and only
- the version
+ the version (optional)
* --enable-inline-test enable Inline-Test Mode Operation
* --help list command line options
* --help-commands [<module prefix>] output matching commands
+ (optional)
* --help-config [<module prefix>] output matching config options
+ (optional)
* --help-counts [<module prefix>] output matching peg counts
+ (optional)
* --help-module <module> output description of given module
* --help-modules list all available modules with brief help
* --help-options <option prefix> output matching command line
- option quick help (same as -?)
+ option quick help (same as -?) (optional)
* --help-plugins list all available plugins with brief help
* --help-signals dump available control signals
* --id-subdir create/use instance subdirectories in logdir instead
thread
* --list-buffers output available inspection buffers
* --list-builtin <module prefix> output matching builtin rules
+ (optional)
* --list-gids [<module prefix>] output matching generators
+ (optional)
* --list-modules [<module type>] list all known modules of given
- type
+ type (optional)
* --list-plugins list all known plugins
* --logid <0xid> log Identifier to uniquely id events for multiple
- snorts (same as -G)
+ snorts (same as -G) (0:65535)
* --lua <chunk> extend/override conf with chunk; may be repeated
* --markup output help in asciidoc compatible format
* --max-packet-threads <count> configure maximum number of packet
- threads (same as -z)
+ threads (same as -z) (0:)
* --nolock-pidfile do not try to lock Snort PID file
* --nostamps don’t include timestamps in log file names
* --pause wait for resume/quit command before processing packets/
* --pcap-list <list> a space separated list of pcaps to read - read
mode is implied
* --pcap-loop <count> read all pcaps <count> times; 0 will read
- until Snort is terminated
+ until Snort is terminated (-1:)
* --pcap-no-filter reset to use no filter when getting pcaps from
file or directory
* --pcap-reload if reading multiple pcaps, reload snort config
* --rule-to-text output plain so rule header to stdout for text
rule on stdin
* --run-prefix <pfx> prepend this to each output file
- * --script-path <path> where to find luajit scripts
+ * --script-path <path> to a luajit script or directory containing
+ luajit scripts
* --shell enable the interactive command line
* --show-plugins list module and plugin versions
- * --skip <n> skip 1st n packets
- * --snaplen <snap> set snaplen of packet (same as -s)
+ * --skip <n> skip 1st n packets (0:)
+ * --snaplen <snap> set snaplen of packet (same as -s) (68:65535)
* --stdin-rules read rules from stdin until EOF or a line starting
with END is read
* --treat-drop-as-alert converts drop, sdrop, and reject rules into
alert rules during startup
* --treat-drop-as-ignore use drop, sdrop, and reject rules to
ignore session traffic when not inline
+ * --unit-test <verbosity> run unit tests with given libcheck output
+ mode (silent | minimal | normal | verbose | env (export
+ CK_VERBOSITY))
* --version show version number (same as -V)
* --warn-all enable all warnings
* --warn-conf warn about configuration issues
* --x2c output ASCII char for given hex (see also --c2x)
* --x2s output ASCII string for given byte code (see also --x2c)
* -? <option prefix> output matching command line option quick help
- (same as --help-options)
+ (same as --help-options) (optional)
* -A <mode> set alert mode: none, cmg, or alert_*
* -B <mask> obfuscated IP addresses in alerts and packet dumps
using CIDR mask
* -C print out payloads with character data only (no hex)
* -D run Snort in background (daemon) mode
* -E enable daemon restart
- * -G <0xid> (same as --logid)
+ * -G <0xid> (same as --logid) (0:65535)
* -H make hash tables deterministic
* -L <mode> logging mode (none, dump, pcap, or log_*)
* -M log messages to syslog (not alerts)
initialization
* -i <iface>… list of interfaces
* -j <port> to listen for telnet connections
- * -k <mode> checksum mode (all,noip,notcp,noudp,noicmp,none)
+ * -k <mode> checksum mode; default is all (all|noip|notcp|noudp|
+ noicmp|none)
* -l <logdir> log to this directory instead of current directory
- * -m <umask> set umask = <umask>
- * -n <count> stop after count packets
+ * -m <umask> set umask = <umask> (0:)
+ * -n <count> stop after count packets (0:)
* -q quiet mode - Don’t show banner and status report
* -r <pcap>… (same as --pcap-list)
- * -s <snap> (same as --snaplen)
+ * -s <snap> (same as --snaplen); default is 1514 (68:65535)
* -t <dir> chroots process to <dir> after initialization
* -u <uname> run snort as <uname> or <uid> after initialization
* -v be verbose
* -y include year in timestamp in the alert and log files
* -z <count> maximum number of packet threads (same as
--max-packet-threads); 0 gets the number of CPU cores reported by
- the system
+ the system; default is 1 (0:)
16.8. Parameters
* bit_list: a list of consecutive integer values from 1 to the
range maximum
* bool: true or false
+ * dynamic: a select type determined by loaded plugins
* enum: a string selected from the given range
* implied: an IPS rule option that takes no value but means true
* int: a whole number in the given range
1:255 }
* int network.new_ttl = 1: use this value for responses and when
normalizing { 1:255 }
+ * int new_http_inspect.request_depth = -1: maximum request message
+ body bytes to examine (-1 no limit) { -1: }
+ * int new_http_inspect.response_depth = -1: maximum response
+ message body bytes to examine (-1 no limit) { -1: }
* bool new_http_inspect.test_input = false: read HTTP messages from
text file
* bool new_http_inspect.test_output = false: print out HTTP section
* int perf_monitor.flow_ports = 1023: maximum ports to track { 0: }
* bool perf_monitor.max = false: calculate theoretical maximum
performance
- * int perf_monitor.max_file_size = 4096: files will be rolled over
- if they exceed this size { 4096: }
+ * int perf_monitor.max_file_size = 4294967295: files will be rolled
+ over if they exceed this size { 4096: }
* int perf_monitor.packets = 10000: minim packets to report { 0: }
* bool perf_monitor.reset = true: reset (clear) statistics after
each reporting interval
compiling into state machine (0 means no maximum) { 0: }
* int search_engine.max_queue_events = 5: maximum number of
matching fast pattern states to queue per packet
- * select search_engine.search_method = ac_bnfa_q: set fast pattern
+ * dynamic search_engine.search_method = ac_bnfa_q: set fast pattern
algorithm - choose available search engine { ac_banded | ac_bnfa
| ac_bnfa_q | ac_full | ac_full_q | ac_sparse | ac_sparse_bands |
- ac_std }
+ ac_std | lowmem | lowmem_q }
* bool search_engine.search_optimize = false: tweak state machine
construction for better performance
* bool search_engine.split_any_any = false: evaluate any-any rules
* implied snort.--rule-to-text: output plain so rule header to
stdout for text rule on stdin
* string snort.--run-prefix: <pfx> prepend this to each output file
- * string snort.--script-path: <path> where to find luajit scripts
+ * string snort.--script-path: <path> to a luajit script or
+ directory containing luajit scripts
* implied snort.--shell: enable the interactive command line
* implied snort.--show-plugins: list module and plugin versions
* int snort.--skip: <n> skip 1st n packets { 0: }
reject rules into alert rules during startup
* implied snort.--treat-drop-as-ignore: use drop, sdrop, and reject
rules to ignore session traffic when not inline
+ * select snort.--unit-test: <verbosity> run unit tests with given
+ libcheck output mode { silent | minimal | normal | verbose | env
+ (export CK_VERBOSITY) }
* implied snort.--version: show version number (same as -V)
* implied snort.--warn-all: enable all warnings
* implied snort.--warn-conf: warn about configuration issues
after initialization
* string snort.-i: <iface>… list of interfaces
* port snort.-j: <port> to listen for telnet connections
- * enum snort.-k = all: <mode> checksum mode
- (all,noip,notcp,noudp,noicmp,none) { all|noip|notcp|noudp|noicmp|
- none }
+ * enum snort.-k = all: <mode> checksum mode; default is all { all|
+ noip|notcp|noudp|noicmp|none }
* string snort.-l: <logdir> log to this directory instead of
current directory
* int snort.-m: <umask> set umask = <umask> { 0: }
* implied snort.-q: quiet mode - Don’t show banner and status
report
* string snort.-r: <pcap>… (same as --pcap-list)
- * int snort.-s = 1514: <snap> (same as --snaplen) { 68:65535 }
+ * int snort.-s = 1514: <snap> (same as --snaplen); default is 1514
+ { 68:65535 }
* string snort.-t: <dir> chroots process to <dir> after
initialization
* string snort.-u: <uname> run snort as <uname> or <uid> after
files
* int snort.-z = 1: <count> maximum number of packet threads (same
as --max-packet-threads); 0 gets the number of CPU cores reported
- by the system { 0: }
+ by the system; default is 1 { 0: }
* string so.~func: name of eval function
* string soid.~: SO rule ID has <gid>|<sid> format, like 3|12345
* int ssh.max_client_bytes = 19600: number of unanswered bytes