Project

General

Profile

Debugging

Unittests

To run unittests from the build directory:

./src/suricata -u -l /tmp/

The -l option is added to overwrite the default log dir. Some tests write logs. This way we don't need root/sudo rights to complete the tests.

valgrind

Running unittests with valgrind enabled:

valgrind -v --trace-children=yes ./src/suricata -u -l /tmp/

The trace children option is necessary if running from the build directory, as "src/suricata" is a script in that case. This is caused by us bundling the libhtp.

gdb with core files

If Suricata crashed with a core dump, lots of info can be retrieved from this core file.

gdb /path/to/suricata /path/to/core

Getting info about the traffic

For example, in a bt like this:

(gdb) bt
#0 0x00007f0302c1af47 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007f0302c1917e in __assert_fail () from
/lib/x86_64-linux-gnu/libc.so.6
#2 0x00000000005ac84d in StreamTcpReassembleAppLayer (tv=0x23258570,
ra_ctx=0x7f02b8001540, ssn=0x7f027c72c9e0,
stream=0x7f027c72ca30, p=0x25057a0) at stream-tcp-reassemble.c:2979
#3 0x0000000000000000 in ?? ()

You can get to the traffic into by going to a frame where you have the
"p" (Packet) variable. In this case frame 2:

(gdb) frame 2

There you can print the entire packet:

(gdb) print *p

Or just individual fields:

(gdp) print p->proto
(gdp) print p->sp
(gdp) print p->dp

Addresses are bit more involved:

(gdb) print p->src.address.address_un_data32[0]
(gdb) print p->dst.address.address_un_data32[0]

This gives you an unsigned int value, you'll have to convert that to the
dotted quad notation yourself.

Example:

(gdb) print p->src.address.address_un_data32[0]
$2 = 721529024

Perl is helpful here:

$ perl -MSocket -e "print inet_ntoa(pack('V',721529024)) . \"\n\";" 
192.168.1.43

For IPv6 you'll have to use:

(gdb) print p->src.address.address_un_data32[0]
(gdb) print p->src.address.address_un_data32[1]
(gdb) print p->src.address.address_un_data32[2]
(gdb) print p->src.address.address_un_data32[3]

To figure out whether it's 4 or 6, print:

(gdb) print p->src.family

Here 2 is IPv4, 10 is IPv6.

In general, the same is true for 'frames' where only the Flow can be accessed. This usually has 'f' or 'flow' as variable name.

(gdb) print *f

Like with the packet, the flow has proto, sp, dp, and src and dst fields.

The flow can be accessed from the packet as well, through p->flow.